Re: Stack usage

John Hughes <[email protected]> Thu, 15 Jan 2009 16:08:24 +0100
Newsgroups gmane.linux.cluster.ssic.devel
Message-ID <[email protected]>
John Hughes wrote:
> So, here's one path that generates a stack overflow warning:
>
> chown -> ... cfs_flush -> ... cfs_proc_write -> ... 
> ext3_ordered_writepage -> ... drbd_send_dblock -> ... tcp_sendpage -> ...
So I've made a patch to reduce the stack usage of cfsd_write, which 
together with the change I'd already done to the cfs_proc stuff seems to 
have got the stack down to the point where cfs over drbd works better 
with 4k stacks.

Not much testing done so far, but I've done a few failovers with success.

(I'd definitely recommend using my overflow patch if you want to try 
this - it's so much easier to debug things when the stackdump doesn't 
crash the machine!).

If anyone does see any stack overflows could they please let me know 
what the backtrace is - thanks.

------------------------------------------------------------------------------
Create and Deploy Rich Internet Apps outside the browser with Adobe(R)AIR(TM)
software. With Adobe AIR, Ajax developers can use existing skills and code to
build responsive, highly engaging applications that combine the power of local
resources and data with the reach of the web. Download the Adobe AIR SDK and
Ajax docs to start building applications today-http://p.sf.net/sfu/adobe-com

_______________________________________________
ssic-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ssic-linux-devel
cfs-stack-usage.patch (text/x-patch, 40.5 KB)
Index: kernel/cluster/ssi/cfs/proc.c
===================================================================
RCS file: /usr/local/lib/cvs-repo/sourceforge-openssi/kernel/cluster/ssi/cfs/proc.c,v
retrieving revision 1.18
retrieving revision 1.18.4.3
diff -u -r1.18 -r1.18.4.3
--- kernel/cluster/ssi/cfs/proc.c	10 Oct 2008 08:10:32 -0000	1.18
+++ kernel/cluster/ssi/cfs/proc.c	15 Jan 2009 14:30:18 -0000	1.18.4.3
@@ -97,6 +97,9 @@
  * Get inode information with just a handle, instead of doing a lookup:
  * for later for reopen
  */
+static int cfs_proc_getinode_remote(struct cfs_server *server, struct cfs_fh *fhandle,
+		  struct inode **ipp);
+
 static int
 cfs_proc_getinode(struct cfs_server *server, struct cfs_fh *fhandle,
 		  struct inode **ipp)
@@ -174,23 +177,7 @@
 			status = -EACCES;
 		HASH_RELE(hp);
 	} else {
-		struct cfsgetinoarg arg;
-		struct cfsdiropres res;
-		struct cfs_nettok res_toks[CFS_NTOKS];
-
-		res.cdr_res_toks = res_toks;
-		arg.cgia_fh = *fhandle;
-		cfstok_get_agent(&arg.cgia_agent);
-		status = rcfscall(server, CFSD_PROC_GETINODE,
-				(xdrproc_t)xdr_cfsgetinoarg,
-				(caddr_t)&arg,
-				(xdrproc_t)xdr_cfsdiropres,
-				(caddr_t)&res);
-		if (!status)
-			status = res.cdr_status;
-		if (!status)
-			*ipp = __cfs_fhget(server->mi_sb, &res.cdr_cdrok,
-					   *ipp);
+		status = cfs_proc_getinode_remote(server, fhandle, ipp);
 	}
 
 sb_error_check:
@@ -202,7 +189,35 @@
 	return status;
 }
 
+static int
+cfs_proc_getinode_remote(struct cfs_server *server, struct cfs_fh *fhandle,
+		  struct inode **ipp)
+{
+	int status;
+
+	struct cfsgetinoarg arg;
+	struct cfsdiropres res;
+	struct cfs_nettok res_toks[CFS_NTOKS];
+
+	res.cdr_res_toks = res_toks;
+	arg.cgia_fh = *fhandle;
+	cfstok_get_agent(&arg.cgia_agent);
+	status = rcfscall(server, CFSD_PROC_GETINODE,
+			(xdrproc_t)xdr_cfsgetinoarg,
+			(caddr_t)&arg,
+			(xdrproc_t)xdr_cfsdiropres,
+			(caddr_t)&res);
+	if (!status)
+		status = res.cdr_status;
+	if (!status)
+		*ipp = __cfs_fhget(server->mi_sb, &res.cdr_cdrok, *ipp);
+	return status;
+}
+
+
 #ifdef CFS_REVALIDATE_GETATTR
+static int cfs_proc_getattr_remote(cfs_mntinfo_t *mip, struct inode *inode);
+
 static int
 cfs_proc_getattr(struct inode *inode)
 {
@@ -221,21 +236,7 @@
 		/* cfsd_getattr() */
 		cfs_update_attr(itoc(inode)->c_hp, inode, 0);
 	} else {
-		struct cfsgaargs args;
-		struct cfsattrstat res;
-
-		args.cgaa_fh = *itocfh(inode);
-		cfstok_get_agent(&args.cgaa_agent);
-
-		status = rcfscall(mip, CFSD_PROC_GETATTR,
-				(xdrproc_t)xdr_cfssaargs,
-				(caddr_t)&args,
-				(xdrproc_t)xdr_cfsattrstat,
-				(caddr_t)&res);
-		if (!status)
-	   		status = res.cns_status;
-		if (!status)
-			cfs_refresh_inode(inode, &(res.cns_attr));
+		status = cfs_proc_getattr_remote(mip, inode)
 	}
 
 sb_error_check:
@@ -246,8 +247,34 @@
 	dprintk("CFS reply getattr\n");
 	return status;
 }
+
+static int
+cfs_proc_getattr_remote(cfs_mntinfo_t *mip, struct inode *inode)
+{
+	int status;
+
+	struct cfsgaargs args;
+	struct cfsattrstat res;
+
+	args.cgaa_fh = *itocfh(inode);
+	cfstok_get_agent(&args.cgaa_agent);
+
+	status = rcfscall(mip, CFSD_PROC_GETATTR,
+			(xdrproc_t)xdr_cfssaargs,
+			(caddr_t)&args,
+			(xdrproc_t)xdr_cfsattrstat,
+			(caddr_t)&res);
+	if (!status)
+   		status = res.cns_status;
+	if (!status)
+		cfs_refresh_inode(inode, &(res.cns_attr));
+
+	return status;
+}
 #endif
 
+static int cfs_proc_setattr_remote(cfs_mntinfo_t *mip, struct inode *inode, struct iattr *attr);
+
 static int
 cfs_proc_setattr(struct inode *inode, struct iattr *attr)
 {
@@ -267,22 +294,7 @@
 		if (!status)
 			cfs_update_attr(itoc(inode)->c_hp, inode, 0);
 	} else {
-		struct cfssaargs args;
-		struct cfsattrstat res;
-
-		args.csaa_fh = *itocfh(inode);
-		args.csaa_sa = *attr;
-		cfstok_get_agent(&args.csaa_agent);
-
-		status = rcfscall(mip, CFSD_PROC_SETATTR,
-				(xdrproc_t)xdr_cfssaargs,
-				(caddr_t)&args,
-				(xdrproc_t)xdr_cfsattrstat,
-				(caddr_t)&res);
-		if (!status)
-	   		status = res.cns_status;
-		if (!status)
-			cfs_refresh_inode(inode, &(res.cns_attr));
+		status = cfs_proc_setattr_remote(mip, inode, attr);
 	}
 
 sb_error_check:
@@ -294,6 +306,32 @@
 	return status;
 }
 
+static int
+cfs_proc_setattr_remote(cfs_mntinfo_t *mip, struct inode *inode, struct iattr *attr)
+{
+	int status;
+
+	struct cfssaargs args;
+	struct cfsattrstat res;
+
+	args.csaa_fh = *itocfh(inode);
+	args.csaa_sa = *attr;
+	cfstok_get_agent(&args.csaa_agent);
+
+	status = rcfscall(mip, CFSD_PROC_SETATTR,
+			(xdrproc_t)xdr_cfssaargs,
+			(caddr_t)&args,
+			(xdrproc_t)xdr_cfsattrstat,
+			(caddr_t)&res);
+	if (!status)
+	  		status = res.cns_status;
+	if (!status)
+		cfs_refresh_inode(inode, &(res.cns_attr));
+	return status;
+}
+
+static int cfs_check_dir_remote(struct inode *dir, struct qstr *name);
+
 int
 cfs_check_dir(struct inode *dir, struct qstr *name)
 {
@@ -304,21 +342,7 @@
 	if (CFS_AT_SERVER(dir)) {
 		status = cfsd_check_dir(itoc(dir)->c_hp, name);
 	} else {
-		cfs_mntinfo_t *mip = itocmi(dir);
-		struct cfslookargs args;
-		int result;
-
-		args.clua_fhandle = *itocfh(dir);
-		args.clua_name = *name;
-		cfstok_get_agent(&args.clua_agent); /* notused */
-
-		status = rcfscall(mip, CFSD_PROC_CHECK_DIR,
-				(xdrproc_t)xdr_cfslookargs,
-				(caddr_t)&args,
-				(xdrproc_t)xdr_int32_t,
-				(caddr_t)&result);
-		if (!status)
-			status = result;
+		status = cfs_check_dir_remote(dir, name);
 	}
 
 	dprintk("CFS reply check_dir: %d\n", status);
@@ -326,6 +350,32 @@
 }
 
 static int
+cfs_check_dir_remote(struct inode *dir, struct qstr *name)
+{
+	int status;
+
+	cfs_mntinfo_t *mip = itocmi(dir);
+	struct cfslookargs args;
+	int result;
+
+	args.clua_fhandle = *itocfh(dir);
+	args.clua_name = *name;
+	cfstok_get_agent(&args.clua_agent); /* notused */
+
+	status = rcfscall(mip, CFSD_PROC_CHECK_DIR,
+			(xdrproc_t)xdr_cfslookargs,
+			(caddr_t)&args,
+			(xdrproc_t)xdr_int32_t,
+			(caddr_t)&result);
+	if (!status)
+		status = result;
+	return status;
+}
+
+static int cfs_proc_lookup_remote(cfs_mntinfo_t *mip,
+	 struct inode *dir, struct qstr *name, struct inode **ipp);
+
+static int
 cfs_proc_lookup(struct inode *dir, struct qstr *name, struct inode **ipp)
 {
 	int status;
@@ -351,24 +401,7 @@
 			HASH_RELE(hp);
 		}
 	} else {
-		struct cfsdiropres res;
-		struct cfslookargs args;
-		struct cfs_nettok res_toks[CFS_NTOKS];
-
-		res.cdr_res_toks = res_toks;
-		args.clua_fhandle = *itocfh(dir);
-		args.clua_name = *name;
-		cfstok_get_agent(&args.clua_agent);
-
-		status = rcfscall(mip, CFSD_PROC_LOOKUP,
-				(xdrproc_t)xdr_cfslookargs,
-				(caddr_t)&args,
-				(xdrproc_t)xdr_cfsdiropres,
-				(caddr_t)&res);
-		if (!status)
-			status = res.cdr_status;
-		if (!status)
-			*ipp = cfs_fhget(dir->i_sb, &(res.cdr_cdrok));
+		status = cfs_proc_lookup_remote(mip, dir, name, ipp);
 	}
 sb_error_check:
 	if (CFS_SB_RETRY(mip, status))
@@ -380,6 +413,36 @@
 }
 
 static int
+cfs_proc_lookup_remote(cfs_mntinfo_t *mip,
+	 struct inode *dir, struct qstr *name, struct inode **ipp)
+{
+	int status;
+
+	struct cfsdiropres res;
+	struct cfslookargs args;
+	struct cfs_nettok res_toks[CFS_NTOKS];
+
+	res.cdr_res_toks = res_toks;
+	args.clua_fhandle = *itocfh(dir);
+	args.clua_name = *name;
+	cfstok_get_agent(&args.clua_agent);
+
+	status = rcfscall(mip, CFSD_PROC_LOOKUP,
+			(xdrproc_t)xdr_cfslookargs,
+			(caddr_t)&args,
+			(xdrproc_t)xdr_cfsdiropres,
+			(caddr_t)&res);
+	if (!status)
+		status = res.cdr_status;
+	if (!status)
+		*ipp = cfs_fhget(dir->i_sb, &(res.cdr_cdrok));
+	return status;
+}
+
+static int cfs_proc_readlink_remote(cfs_mntinfo_t *mip,
+	struct inode *inode, void *buffer, unsigned int bufsiz);
+
+static int
 cfs_proc_readlink(struct inode *inode, void *buffer, unsigned int bufsiz)
 {
 	int			status;
@@ -403,27 +466,7 @@
 			cfs_update_attr(itoc(inode)->c_hp, inode, 0);
 		}
 	} else {
-		struct cfsrdlnres res;
-		struct cfsrdlnargs args;
-
-		res.crl_data = buffer;
-		args.crl_fh = *itocfh(inode);
-		cfstok_get_agent(&args.crl_agent);
-
-		status = rcfscall(mip, CFSD_PROC_READLINK,
-				(xdrproc_t)xdr_cfsrdlnargs,
-				(caddr_t)&args,
-				(xdrproc_t)xdr_cfsrdlnres,
-				(caddr_t)&res);
-
-		if (!status)
-			status = res.crl_status;
-		if (!status) {
-			/* Null terminate buffer */
-			((char *)buffer)[res.crl_count] = 0;
-
-			cfs_refresh_inode(inode, &(res.crl_attr));
-		}
+		status = cfs_proc_readlink_remote(mip, inode, buffer, bufsiz);
 	}
 sb_error_check:
 	if (CFS_SB_RETRY(mip, status))
@@ -434,9 +477,49 @@
 	return status;
 }
 
+static int
+cfs_proc_readlink_remote(cfs_mntinfo_t *mip,
+	struct inode *inode, void *buffer, unsigned int bufsiz)
+{
+	int status;
+
+	struct cfsrdlnres res;
+	struct cfsrdlnargs args;
+
+	res.crl_data = buffer;
+	args.crl_fh = *itocfh(inode);
+	cfstok_get_agent(&args.crl_agent);
+
+	status = rcfscall(mip, CFSD_PROC_READLINK,
+			(xdrproc_t)xdr_cfsrdlnargs,
+			(caddr_t)&args,
+			(xdrproc_t)xdr_cfsrdlnres,
+			(caddr_t)&res);
+
+	if (!status)
+		status = res.crl_status;
+	if (!status) {
+		/* Null terminate buffer */
+		((char *)buffer)[res.crl_count] = 0;
+
+		cfs_refresh_inode(inode, &(res.crl_attr));
+	}
+	return status;
+}
+
 /* The async arg is used to inform this routine it is being called from
  * an async handler process.  It should not hang on a down hard mount.
  */
+#ifdef CFS_PAGEVEC
+static int cfs_proc_read_remote (cfs_mntinfo_t *mip, struct inode *inode,
+				 struct cfs_read_data *data, 
+				 struct kvec *kvec, int vlen);
+#else
+static int cfs_proc_read_remote (cfs_mntinfo_t *mip, 
+		struct inode *inode, loff_t offset, unsigned int count,
+                void *buffer);
+#endif
+
 static int
 #ifdef CFS_PAGEVEC
 cfs_proc_read(struct cfs_read_data *data)
@@ -496,59 +579,90 @@
 #endif
 		}
 	} else {
-		struct cfsreadargs args;
-		struct cfsrdresults *res_p = NULL;
-		int rval;
 #ifdef CFS_PAGEVEC
-		unsigned long mycount = data->count;
+		status = cfs_proc_read_remote (mip, inode, data, kvec, vlen);
 #else
-		int mycount = count;
+		status = cfs_proc_read_remote (mip, inode, offset, count, buffer)
 #endif
+	}
 
-		args.cra_fhandle = *itocfh(inode);
 #ifdef CFS_PAGEVEC
-		args.cra_offset = data->offset;
-		args.cra_pgbase = data->pgbase;
+	CFS_PAGEVEC_UNMAP(data, kvec);
+#endif
+sb_error_check:
+	if (async ? CFS_SB_RETRY_NOHANG(mip, status):CFS_SB_RETRY(mip, status))
+		goto sb_down_retry;
+	CFS_SB_FSOP_DONE(mip);
 
-		status = RCFS_READ(mip->mi_server,&rval,
-				   &args, &res_p, &mycount, &kvec, &vlen);
+	dprintk("CFS reply read: %d\n", status);
+	return status;
+}
+
+static int 
+#ifdef CFS_PAGEVEC
+cfs_proc_read_remote (cfs_mntinfo_t *mip, struct inode *inode, 
+		struct cfs_read_data *data, struct kvec *kvec, int vlen)
 #else
-		args.cra_offset = offset;
+cfs_proc_read_remote (cfs_mntinfo_t *mip, struct inode *inode,
+		loff_t offset, unsigned int count,
+                void *buffer)
+#endif
+{
+	int status;
 
-		status = RCFS_READ(mip->mi_server,&rval,
-				   &args, &res_p, (char **)&buffer,&mycount);
+	struct cfsreadargs args;
+	struct cfsrdresults *res_p = NULL;
+	int rval;
+#ifdef CFS_PAGEVEC
+	unsigned long mycount = data->count;
+#else
+	int mycount = count;
 #endif
 
-		if (status != 0 || rval != 0)
-			status = -ETIMEDOUT;
-		if (status == 0) {
-			status = res_p->crr_status;
-			if (status == 0) {
+	args.cra_fhandle = *itocfh(inode);
 #ifdef CFS_PAGEVEC
-				data->res_count = mycount;
+	args.cra_offset = data->offset;
+	args.cra_pgbase = data->pgbase;
+
+	status = RCFS_READ(mip->mi_server,&rval,
+			   &args, &res_p, &mycount, &kvec, &vlen);
+#else
+	args.cra_offset = offset;
+
+	status = RCFS_READ(mip->mi_server,&rval,
+			   &args, &res_p, (char **)&buffer,&mycount);
 #endif
-				status = (ssize_t)mycount;
-				cfs_refresh_inode(inode, &(res_p->crr_attr));
-			}
-			(void) xdr_free(xdr_cfsrdresults_p, &res_p);
-		}
-	}
 
+	if (status != 0 || rval != 0)
+		status = -ETIMEDOUT;
+	if (status == 0) {
+		status = res_p->crr_status;
+		if (status == 0) {
 #ifdef CFS_PAGEVEC
-	CFS_PAGEVEC_UNMAP(data, kvec);
+			data->res_count = mycount;
 #endif
-sb_error_check:
-	if (async ? CFS_SB_RETRY_NOHANG(mip, status):CFS_SB_RETRY(mip, status))
-		goto sb_down_retry;
-	CFS_SB_FSOP_DONE(mip);
+			status = (ssize_t)mycount;
+			cfs_refresh_inode(inode, &(res_p->crr_attr));
+		}
+		(void) xdr_free(xdr_cfsrdresults_p, &res_p);
+	}
 
-	dprintk("CFS reply read: %d\n", status);
 	return status;
 }
 
 /* The async arg is used to inform this routine it is being called from
  * an async handler process.  It should not hang on a down hard mount.
  */
+#ifdef CFS_PAGEVEC
+static int cfs_proc_write_remote(cfs_mntinfo_t *mip, struct inode *inode,
+		struct cfs_write_data *data,
+		struct kvec *kvec, int vlen);
+#else
+static int cfs_proc_write_remote(cfs_mntinfo_t *mip,
+		struct inode *inode, loff_t offset, unsigned int count,
+		void *buffer, int stable);
+#endif
+
 static int
 #ifdef CFS_PAGEVEC
 cfs_proc_write(struct cfs_write_data *data)
@@ -602,30 +716,11 @@
 #endif
 		}
 	} else {
-		struct cfswriteargs args;
-		struct cfswriteres *res_p = NULL;
-		int rval;
-
-		args.cwa_fhandle = *itocfh(inode);
-#ifdef CFS_PAGEVEC
-		args.cwa_offset = data->offset;
-		args.cwa_stable = data->stable;
-		status = RCFS_WRITE(mip->mi_server, &rval, &args, &res_p,
-				    (unsigned long)data->count, &kvec, vlen);
-#else
-		args.cwa_offset = offset;
-		args.cwa_stable = stable;
-		status = RCFS_WRITE(mip->mi_server, &rval, &args, &res_p,
-				    buffer, count);
+#ifdef CFS_PAGEVEC
+		status = cfs_proc_write_remote(mip, inode, data, kvec, vlen);
+#else
+		status = cfs_proc_write_remote(mip, inode, offset, count, buffer, stable);
 #endif
-		if (status != 0 || rval != 0)
-			status = -ETIMEDOUT;
-		if (status == 0) {
-			status = res_p->cwr_status;
-			if (status == 0)
-				cfs_refresh_inode(inode, &res_p->cwr_attr);
-			(void) xdr_free(xdr_cfswriteres_p, &res_p);
-		}
 	}
 
 #ifdef CFS_PAGEVEC
@@ -645,6 +740,51 @@
 }
 
 static int
+#ifdef CFS_PAGEVEC
+cfs_proc_write_remote(cfs_mntinfo_t *mip, struct inode *inode,
+		struct cfs_write_data *data,
+		struct kvec *kvec, int vlen)
+#else
+cfs_proc_write_remote(cfs_mntinfo_t *mip,
+		struct inode *inode, loff_t offset, unsigned int count,
+		void *buffer, int stable)
+#endif
+{
+	int status;
+
+	struct cfswriteargs args;
+	struct cfswriteres *res_p = NULL;
+	int rval;
+
+	args.cwa_fhandle = *itocfh(inode);
+#ifdef CFS_PAGEVEC
+	args.cwa_offset = data->offset;
+	args.cwa_stable = data->stable;
+	status = RCFS_WRITE(mip->mi_server, &rval, &args, &res_p,
+			    (unsigned long)data->count, &kvec, vlen);
+#else
+	args.cwa_offset = offset;
+	args.cwa_stable = stable;
+	status = RCFS_WRITE(mip->mi_server, &rval, &args, &res_p,
+			    buffer, count);
+#endif
+	if (status != 0 || rval != 0)
+		status = -ETIMEDOUT;
+	if (status == 0) {
+		status = res_p->cwr_status;
+		if (status == 0)
+			cfs_refresh_inode(inode, &res_p->cwr_attr);
+		(void) xdr_free(xdr_cfswriteres_p, &res_p);
+	}
+
+	return status;
+}
+
+static int cfs_proc_create_remote(cfs_mntinfo_t *mip,
+		struct inode *dir, struct qstr *name, int mode,
+		int flags, struct inode **ipp);
+
+static int
 cfs_proc_create(struct inode *dir, struct qstr *name, int mode,
 		int flags, struct inode **ipp)
 {
@@ -696,33 +836,7 @@
 			HASH_RELE(hp);
 		}
 	} else {
-		struct cfscreatres res;
-		struct cfs_nettok res_toks[CFS_NTOKS];
-		struct cfscreatargs args;
-
-		res.ccr_res_toks = res_toks;
-		args.cca_fhandle = *itocfh(dir);
-		args.cca_name = *name;
-		args.cca_mode = mode;
-		args.cca_type = S_IFREG;
-		args.cca_dev = 0;
-		args.cca_flags = flags;
-		args.fsuid = current->fsuid;
-		args.fsgid = current->fsgid;
-		cfstok_get_agent(&args.cca_agent);
-		status = rcfscall(mip, CFSD_PROC_CREATE,
-				(xdrproc_t)xdr_cfscreatargs,
-				(caddr_t)&args,
-				(xdrproc_t)xdr_cfscreatres,
-				(caddr_t)&res);
-		if (!status) {
-			status = res.ccr_status;
-		}
-		if (!status) {
-			cfs_refresh_inode(dir, &(res.ccr_dirattr));
-
-			*ipp = cfs_fhget(dir->i_sb, &(res.ccr_ok));
-		}
+		status = cfs_proc_create_remote(mip, dir, name, mode, flags, ipp);
 	}
 
 	/* We pre-checked that the file didn't exist, This must have
@@ -742,6 +856,47 @@
 }
 
 static int
+cfs_proc_create_remote(cfs_mntinfo_t *mip,
+		struct inode *dir, struct qstr *name, int mode,
+		int flags, struct inode **ipp)
+{
+	int status;
+
+	struct cfscreatres res;
+	struct cfs_nettok res_toks[CFS_NTOKS];
+	struct cfscreatargs args;
+
+	res.ccr_res_toks = res_toks;
+	args.cca_fhandle = *itocfh(dir);
+	args.cca_name = *name;
+	args.cca_mode = mode;
+	args.cca_type = S_IFREG;
+	args.cca_dev = 0;
+	args.cca_flags = flags;
+	args.fsuid = current->fsuid;
+	args.fsgid = current->fsgid;
+	cfstok_get_agent(&args.cca_agent);
+	status = rcfscall(mip, CFSD_PROC_CREATE,
+			(xdrproc_t)xdr_cfscreatargs,
+			(caddr_t)&args,
+			(xdrproc_t)xdr_cfscreatres,
+			(caddr_t)&res);
+	if (!status) {
+		status = res.ccr_status;
+	}
+	if (!status) {
+		cfs_refresh_inode(dir, &(res.ccr_dirattr));
+
+		*ipp = cfs_fhget(dir->i_sb, &(res.ccr_ok));
+	}
+
+	return status;
+}
+
+static int cfs_proc_remove_remote(cfs_mntinfo_t *mip,
+	struct inode *dir, struct qstr *name, struct inode *ip);
+
+static int
 cfs_proc_remove(struct inode *dir, struct qstr *name, struct inode *ip)
 {
 	int			status;
@@ -767,24 +922,7 @@
 			HASH_RELE(hp);
 		}
 	} else {
-		struct cfsrmres res;
-		struct cfsunlinkargs args;
-
-		args.crma_fhandle = *itocfh(dir);
-		args.crma_qstr = *name;
-
-		status = rcfscall(mip, CFSD_PROC_UNLINK,
-				(xdrproc_t)xdr_cfsunlinkargs,
-				(caddr_t)&args,
-				(xdrproc_t)xdr_cfsrmres,
-				(caddr_t)&res);
-
-		if (!status)
-			status = res.crms_status;
-		if (!status) {
-			cfs_refresh_inode(dir, &(res.crms_dirattr));
-			cfs_refresh_inode(ip, &(res.crms_attr));
-		}
+		status = cfs_proc_remove_remote(mip, dir, name, ip);
 	}
 
 	/* Ignore error due to retransmitted failover request */
@@ -802,6 +940,38 @@
 }
 
 static int
+cfs_proc_remove_remote(cfs_mntinfo_t *mip,
+	struct inode *dir, struct qstr *name, struct inode *ip)
+{
+	int status;
+
+	struct cfsrmres res;
+	struct cfsunlinkargs args;
+
+	args.crma_fhandle = *itocfh(dir);
+	args.crma_qstr = *name;
+
+	status = rcfscall(mip, CFSD_PROC_UNLINK,
+			(xdrproc_t)xdr_cfsunlinkargs,
+			(caddr_t)&args,
+			(xdrproc_t)xdr_cfsrmres,
+			(caddr_t)&res);
+
+	if (!status)
+		status = res.crms_status;
+	if (!status) {
+		cfs_refresh_inode(dir, &(res.crms_dirattr));
+		cfs_refresh_inode(ip, &(res.crms_attr));
+	}
+
+	return status;
+}
+
+static int cfs_proc_rename_remote(cfs_mntinfo_t *mip,
+		struct inode *old_dir, struct qstr *old_name, struct inode *oip,
+		struct inode *new_dir, struct qstr *new_name, struct inode *nip);
+
+static int
 cfs_proc_rename(struct inode *old_dir, struct qstr *old_name, struct inode *oip,
 		struct inode *new_dir, struct qstr *new_name, struct inode *nip)
 {
@@ -839,32 +1009,12 @@
 				HASH_RELE(nhp);
 		}
 	} else {
-		struct cfsrnmres res;
-		struct cfsrnmargs args;
-
-		args.crna_from.cda_fhandle = *itocfh(old_dir);
-		args.crna_from.cda_name = *old_name;
-		args.crna_to.cda_fhandle = *itocfh(new_dir);
-		args.crna_to.cda_name = *new_name;
-		cfstok_get_agent(&args.crna_agent);
-
-		status = rcfscall(mip, CFSD_PROC_RENAME,
-				(xdrproc_t)xdr_cfsrnmargs,
-				(caddr_t)&args,
-				(xdrproc_t)xdr_cfsrnmres,
-				(caddr_t)&res);
+		/* Handle remote case in another proc so it's large
+		   stack usage doesn't eat up space for local case */
 
-		if (!status) {
-			status = res.crnmr_status;
-		}
-		if (!status) {
-			cfs_refresh_inode(old_dir, &res.crnmr_odirattr);
-			if (new_dir != old_dir)
-				cfs_refresh_inode(new_dir, &res.crnmr_ndirattr);
-			cfs_refresh_inode(oip, &res.crnmr_oattr);
-			if (nip)
-				cfs_refresh_inode(nip, &res.crnmr_nattr);
-		}
+		status = cfs_proc_rename_remote(mip, 
+				old_dir, old_name, oip,
+				new_dir, new_name, nip);
 	}
 
 	/* Ignore error, get inode due to retransmitted failover request */
@@ -881,6 +1031,51 @@
 	return status;
 }
 
+/*
+ * Break out the remote path from cfs_proc_rename so we reduce stack
+ * usage on the local path.  Ugly.  JH
+ *
+ */
+
+static int
+cfs_proc_rename_remote(cfs_mntinfo_t *mip,
+		struct inode *old_dir, struct qstr *old_name, struct inode *oip,
+		struct inode *new_dir, struct qstr *new_name, struct inode *nip)
+{
+	int status;
+
+	struct cfsrnmres res;
+	struct cfsrnmargs args;
+
+	args.crna_from.cda_fhandle = *itocfh(old_dir);
+	args.crna_from.cda_name = *old_name;
+	args.crna_to.cda_fhandle = *itocfh(new_dir);
+	args.crna_to.cda_name = *new_name;
+	cfstok_get_agent(&args.crna_agent);
+
+	status = rcfscall(mip, CFSD_PROC_RENAME,
+			(xdrproc_t)xdr_cfsrnmargs,
+			(caddr_t)&args,
+			(xdrproc_t)xdr_cfsrnmres,
+			(caddr_t)&res);
+
+	if (!status) {
+		status = res.crnmr_status;
+	}
+	if (!status) {
+		cfs_refresh_inode(old_dir, &res.crnmr_odirattr);
+		if (new_dir != old_dir)
+			cfs_refresh_inode(new_dir, &res.crnmr_ndirattr);
+		cfs_refresh_inode(oip, &res.crnmr_oattr);
+		if (nip)
+			cfs_refresh_inode(nip, &res.crnmr_nattr);
+	}
+	return status;
+}
+
+static int cfs_proc_link_remote(cfs_mntinfo_t *mip,
+	struct inode *inode, struct inode *dir, struct qstr *name);
+
 static int
 cfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
 {
@@ -924,28 +1119,7 @@
 			cfs_update_attr(itoc(inode)->c_hp, inode, 0);
 		}
 	} else {
-		struct cfsrmres res;
-		struct cfslinkargs args;
-
-		args.cla_from = *itocfh(inode);
-		args.cla_to.cda_fhandle = *itocfh(dir);
-		args.cla_to.cda_name = *name;
-		args.fsuid = current->fsuid;
-		args.fsgid = current->fsgid;
-		cfstok_get_agent(&args.cla_agent);
-
-		status = rcfscall(mip, CFSD_PROC_LINK,
-				(xdrproc_t)xdr_cfslinkargs,
-				(caddr_t)&args,
-				(xdrproc_t)xdr_cfsrmres,
-				(caddr_t)&res);
-
-		if (!status)
-			status = res.crms_status;
-		if (!status) {
-			cfs_refresh_inode(dir, &(res.crms_dirattr));
-			cfs_refresh_inode(inode, &(res.crms_attr));
-		}
+		status = cfs_proc_link_remote(mip, inode, dir, name);
 	}
 
 	/* Ignore this error due to retransmitted failover request */
@@ -963,6 +1137,40 @@
 }
 
 static int
+cfs_proc_link_remote(cfs_mntinfo_t *mip,
+	struct inode *inode, struct inode *dir, struct qstr *name)
+{
+	int status;
+
+	struct cfsrmres res;
+	struct cfslinkargs args;
+
+	args.cla_from = *itocfh(inode);
+	args.cla_to.cda_fhandle = *itocfh(dir);
+	args.cla_to.cda_name = *name;
+	args.fsuid = current->fsuid;
+	args.fsgid = current->fsgid;
+	cfstok_get_agent(&args.cla_agent);
+
+	status = rcfscall(mip, CFSD_PROC_LINK,
+			(xdrproc_t)xdr_cfslinkargs,
+			(caddr_t)&args,
+			(xdrproc_t)xdr_cfsrmres,
+			(caddr_t)&res);
+
+	if (!status)
+		status = res.crms_status;
+	if (!status) {
+		cfs_refresh_inode(dir, &(res.crms_dirattr));
+		cfs_refresh_inode(inode, &(res.crms_attr));
+	}
+	return status;
+}
+
+static int cfs_proc_symlink_remote(cfs_mntinfo_t *mip,
+	struct inode *dir, struct qstr *name, const char *path,
+			struct inode **ipp);
+static int
 cfs_proc_symlink(struct inode *dir, struct qstr *name, const char *path,
 			struct inode **ipp)
 {
@@ -1016,33 +1224,7 @@
 			HASH_RELE(hp);
 		}
 	} else {
-		struct cfscreatres res;
-		struct cfs_nettok res_toks[CFS_NTOKS];
-		struct cfsslargs args;
-
-		res.ccr_res_toks = res_toks;
-		args.csla_from.cda_fhandle = *itocfh(dir);
-		args.csla_from.cda_name = *name;
-		args.csla_tnm = (char *)path;
-		args.fsuid = current->fsuid;
-		args.fsgid = current->fsgid;
-		cfstok_get_agent(&args.csla_agent);
-
-		status = rcfscall(mip, CFSD_PROC_SYMLINK,
-				(xdrproc_t)xdr_cfsslargs,
-				(caddr_t)&args,
-				(xdrproc_t)xdr_cfscreatres,
-				(caddr_t)&res);
-
-		if (!status) {
-			status = res.ccr_status;
-			if (!status) {
-				/* Load attributes from server for dir */
-				cfs_refresh_inode(dir, &(res.ccr_dirattr));
-
-				*ipp = cfs_fhget(dir->i_sb, &(res.ccr_ok));
-			}
-		}
+		status = cfs_proc_symlink_remote(mip, dir, name, path, ipp);
 	}
 	/* Ignore error, get inode due to retransmitted failover request */
 	if (status == -EEXIST && CFS_SB_HARD_MIP(itocmi(dir)) &&
@@ -1061,6 +1243,48 @@
 }
 
 static int
+cfs_proc_symlink_remote(cfs_mntinfo_t *mip,
+			struct inode *dir, struct qstr *name, const char *path,
+			struct inode **ipp)
+{
+	int status;
+
+	struct cfscreatres res;
+	struct cfs_nettok res_toks[CFS_NTOKS];
+	struct cfsslargs args;
+
+	res.ccr_res_toks = res_toks;
+	args.csla_from.cda_fhandle = *itocfh(dir);
+	args.csla_from.cda_name = *name;
+	args.csla_tnm = (char *)path;
+	args.fsuid = current->fsuid;
+	args.fsgid = current->fsgid;
+	cfstok_get_agent(&args.csla_agent);
+
+	status = rcfscall(mip, CFSD_PROC_SYMLINK,
+			(xdrproc_t)xdr_cfsslargs,
+			(caddr_t)&args,
+			(xdrproc_t)xdr_cfscreatres,
+			(caddr_t)&res);
+
+	if (!status) {
+		status = res.ccr_status;
+		if (!status) {
+			/* Load attributes from server for dir */
+			cfs_refresh_inode(dir, &(res.ccr_dirattr));
+
+			*ipp = cfs_fhget(dir->i_sb, &(res.ccr_ok));
+		}
+	}
+
+	return status;
+}
+
+static int cfs_proc_mkdir_remote(cfs_mntinfo_t *mip,
+		struct inode *dir, struct qstr *name, int mode,
+	       struct inode **ipp);
+
+static int
 cfs_proc_mkdir(struct inode *dir, struct qstr *name, int mode,
 	       struct inode **ipp)
 {
@@ -1115,34 +1339,7 @@
 			HASH_RELE(hp);
 		}
 	} else {
-		struct cfscreatres res;
-		struct cfscreatargs args;
-		struct cfs_nettok res_toks[CFS_NTOKS];
-
-		res.ccr_res_toks = res_toks;
-		args.cca_fhandle = *itocfh(dir);
-		args.cca_name = *name;
-		args.cca_mode = mode;
-		args.cca_type = S_IFDIR;
-		args.cca_dev = 0;
-		args.fsuid = current->fsuid;
-		args.fsgid = current->fsgid;
-		cfstok_get_agent(&args.cca_agent);
-
-		status = rcfscall(mip, CFSD_PROC_MKDIR,
-				(xdrproc_t)xdr_cfscreatargs,
-				(caddr_t)&args,
-				(xdrproc_t)xdr_cfscreatres,
-				(caddr_t)&res);
-		if (status == 0) {
-			status = res.ccr_status;
-			if (status == 0) {
-				/* Load attributes from server for dir */
-				cfs_refresh_inode(dir, &(res.ccr_dirattr));
-
-				*ipp = cfs_fhget(dir->i_sb, &(res.ccr_ok));
-			}
-		}
+		status = cfs_proc_mkdir_remote(mip, dir, name, mode, ipp);
 	}
 
 	/* Ignore error, get inode due to retransmitted failover request */
@@ -1162,6 +1359,48 @@
 }
 
 static int
+cfs_proc_mkdir_remote(cfs_mntinfo_t *mip,
+		struct inode *dir, struct qstr *name, int mode,
+		struct inode **ipp)
+{
+	int status;
+
+	struct cfscreatres res;
+	struct cfscreatargs args;
+	struct cfs_nettok res_toks[CFS_NTOKS];
+
+	res.ccr_res_toks = res_toks;
+	args.cca_fhandle = *itocfh(dir);
+	args.cca_name = *name;
+	args.cca_mode = mode;
+	args.cca_type = S_IFDIR;
+	args.cca_dev = 0;
+	args.fsuid = current->fsuid;
+	args.fsgid = current->fsgid;
+	cfstok_get_agent(&args.cca_agent);
+
+	status = rcfscall(mip, CFSD_PROC_MKDIR,
+			(xdrproc_t)xdr_cfscreatargs,
+			(caddr_t)&args,
+			(xdrproc_t)xdr_cfscreatres,
+			(caddr_t)&res);
+	if (status == 0) {
+		status = res.ccr_status;
+		if (status == 0) {
+			/* Load attributes from server for dir */
+			cfs_refresh_inode(dir, &(res.ccr_dirattr));
+
+			*ipp = cfs_fhget(dir->i_sb, &(res.ccr_ok));
+		}
+	}
+
+	return status;
+}
+
+static int cfs_proc_rmdir_remote(cfs_mntinfo_t *mip, 
+	struct inode *dir, struct qstr *name, struct inode *ip);
+
+static int
 cfs_proc_rmdir(struct inode *dir, struct qstr *name, struct inode *ip)
 {
 	int status;
@@ -1187,23 +1426,7 @@
 			HASH_RELE(hp);
 		}
 	} else {
-		struct cfsrmdrargs args;
-		struct cfsrmres res;
-
-		args.crmda_fhandle = *itocfh(dir);
-		args.crmda_name = *name;
-
-		status = rcfscall(mip, CFSD_PROC_RMDIR,
-				(xdrproc_t)xdr_cfsrmdrargs,
-				(caddr_t)&args,
-				(xdrproc_t)xdr_cfsrmres,
-				(caddr_t)&res);
-		if (!status)
-			status = res.crms_status;
-		if (!status) {
-			cfs_refresh_inode(dir, &(res.crms_dirattr));
-			cfs_refresh_inode(ip, &(res.crms_attr));
-		}
+		status = cfs_proc_rmdir_remote(mip, dir, name, ip);
 	}
 	/* Ignore error due to retransmitted failover request */
 	if (status == -ENOENT && CFS_SB_HARD_MIP(itocmi(dir)) &&
@@ -1220,6 +1443,33 @@
 }
 
 static int
+cfs_proc_rmdir_remote(cfs_mntinfo_t *mip, 
+	struct inode *dir, struct qstr *name, struct inode *ip)
+{
+	int status;
+
+	struct cfsrmdrargs args;
+	struct cfsrmres res;
+
+	args.crmda_fhandle = *itocfh(dir);
+	args.crmda_name = *name;
+
+	status = rcfscall(mip, CFSD_PROC_RMDIR,
+			(xdrproc_t)xdr_cfsrmdrargs,
+			(caddr_t)&args,
+			(xdrproc_t)xdr_cfsrmres,
+			(caddr_t)&res);
+	if (!status)
+		status = res.crms_status;
+	if (!status) {
+		cfs_refresh_inode(dir, &(res.crms_dirattr));
+		cfs_refresh_inode(ip, &(res.crms_attr));
+	}
+
+	return status;
+}
+
+static int
 cfs_proc_readdir(struct inode *dir,
 		 __u32 cookie, void *entry,
 		 unsigned int size)
@@ -1258,6 +1508,10 @@
 	return status;
 }
 
+static int cfs_proc_mknod_remote(cfs_mntinfo_t *mip,
+		struct inode *dir, struct qstr *name, int mode,
+	       dev_t rdev, struct inode **ipp);
+
 static int
 cfs_proc_mknod(struct inode *dir, struct qstr *name, int mode,
 	       dev_t rdev, struct inode **ipp)
@@ -1315,32 +1569,7 @@
 			HASH_RELE(hp);
 		}
 	} else {
-		struct cfscreatres res;
-		struct cfscreatargs args;
-		struct cfs_nettok res_toks[CFS_NTOKS];
-
-		res.ccr_res_toks = res_toks;
-		args.cca_fhandle = *itocfh(dir);
-		args.cca_name = *name;
-		args.cca_mode = mode;
-		args.cca_type = type;
-		args.cca_dev = rdev;
-		args.fsuid = current->fsuid;
-		args.fsgid = current->fsgid;
-		cfstok_get_agent(&args.cca_agent);
-		status = rcfscall(mip, CFSD_PROC_MKDIR,
-				(xdrproc_t)xdr_cfscreatargs,
-				(caddr_t)&args,
-				(xdrproc_t)xdr_cfscreatres,
-				(caddr_t)&res);
-		if (!status)
-			status = res.ccr_status;
-		if (!status) {
-			/* Load attributes from server for dir */
-			cfs_refresh_inode(dir, &(res.ccr_dirattr));
-
-			*ipp = cfs_fhget(dir->i_sb, &(res.ccr_ok));
-		}
+		status = cfs_proc_mknod_remote(mip, dir, name, mode, rdev, ipp);
 	}
 
 	/* Ignore error, get inode due to retransmitted failover request */
@@ -1360,6 +1589,46 @@
 }
 
 static int
+cfs_proc_mknod_remote(cfs_mntinfo_t *mip,
+		struct inode *dir, struct qstr *name, int mode,
+		dev_t rdev, struct inode **ipp)
+{
+	int status;
+
+	int type = mode & S_IFMT;
+	struct cfscreatres res;
+	struct cfscreatargs args;
+	struct cfs_nettok res_toks[CFS_NTOKS];
+
+	res.ccr_res_toks = res_toks;
+	args.cca_fhandle = *itocfh(dir);
+	args.cca_name = *name;
+	args.cca_mode = mode;
+	args.cca_type = type;
+	args.cca_dev = rdev;
+	args.fsuid = current->fsuid;
+	args.fsgid = current->fsgid;
+	cfstok_get_agent(&args.cca_agent);
+	status = rcfscall(mip, CFSD_PROC_MKDIR,
+			(xdrproc_t)xdr_cfscreatargs,
+			(caddr_t)&args,
+			(xdrproc_t)xdr_cfscreatres,
+			(caddr_t)&res);
+	if (!status)
+		status = res.ccr_status;
+	if (!status) {
+		/* Load attributes from server for dir */
+		cfs_refresh_inode(dir, &(res.ccr_dirattr));
+
+		*ipp = cfs_fhget(dir->i_sb, &(res.ccr_ok));
+	}
+
+	return status;
+}
+
+static int cfs_proc_statfs_remote(struct cfs_server *server, struct kstatfs *info);
+
+static int
 cfs_proc_statfs(struct cfs_server *server, struct kstatfs *info)
 {
 	int	status;
@@ -1376,17 +1645,7 @@
 	if (CFS_AT_SERVER_MIP(server)) {
 		status = cfsd_statfs(server->mi_sb, info);
 	} else {
-		struct cfsstatfs res;
-
-		status = rcfscall(server, CFSD_PROC_STATFS,
-				(xdrproc_t)xdr_cfhandle_t,
-		(caddr_t)&(itoc(server->mi_sb->s_root->d_inode)->c_fh),
-				(xdrproc_t) xdr_cfsstatfs,
-				(caddr_t)&res);
-		if (!status)
-			status = res.csfs_status;
-		if (!status)
-			*info = res.csfs_statfs;
+		status = cfs_proc_statfs_remote(server, info);
 	}
 
 sb_error_check:
@@ -1398,6 +1657,25 @@
 	return status;
 }
 
+static int
+cfs_proc_statfs_remote(struct cfs_server *server, struct kstatfs *info)
+{
+	int status;
+
+	struct cfsstatfs res;
+
+	status = rcfscall(server, CFSD_PROC_STATFS,
+			(xdrproc_t)xdr_cfhandle_t,
+	(caddr_t)&(itoc(server->mi_sb->s_root->d_inode)->c_fh),
+			(xdrproc_t) xdr_cfsstatfs,
+			(caddr_t)&res);
+	if (!status)
+		status = res.csfs_status;
+	if (!status)
+		*info = res.csfs_statfs;
+	return status;
+}
+
 #define QUADLEN(l)		(((l) + 3) >> 2)
 
 u32 *
@@ -1425,6 +1703,9 @@
 	return p;
 }
 
+static int cfs_proc_revalidate_remote(cfs_mntinfo_t *mip,
+	struct inode *dir, struct qstr *name, unsigned long *inump);
+
 static int
 cfs_proc_revalidate(struct inode *dir, struct qstr *name, unsigned long *inump)
 {
@@ -1449,21 +1730,7 @@
 			HASH_RELE(hp);
 		}
 	} else {
-		struct cfsdiropargs args;
-		struct cfsrevres res;
-
-		args.cda_fhandle = *itocfh(dir);
-		args.cda_name = *name;
-
-		status = rcfscall(mip, CFSD_PROC_REVALIDATE,
-				(xdrproc_t)xdr_cfsdiropargs,
-				(caddr_t)&args,
-				(xdrproc_t)xdr_cfsrevres,
-				(caddr_t)&res);
-		if (!status)
-			status = res.rvr_status;
-		if (!status)
-			*inump = res.rvr_inum;
+		status = cfs_proc_revalidate_remote(mip, dir, name, inump);
 	}
 sb_error_check:
 	if (CFS_SB_RETRY(mip, status))
@@ -1474,9 +1741,42 @@
 	return status;
 }
 
+static int
+cfs_proc_revalidate_remote(cfs_mntinfo_t *mip,
+	struct inode *dir, struct qstr *name, unsigned long *inump)
+{
+	int status;
+
+	struct cfsdiropargs args;
+	struct cfsrevres res;
+
+	args.cda_fhandle = *itocfh(dir);
+	args.cda_name = *name;
+
+	status = rcfscall(mip, CFSD_PROC_REVALIDATE,
+			(xdrproc_t)xdr_cfsdiropargs,
+			(caddr_t)&args,
+			(xdrproc_t)xdr_cfsrevres,
+			(caddr_t)&res);
+	if (!status)
+		status = res.rvr_status;
+	if (!status)
+		*inump = res.rvr_inum;
+	return status;
+}
+
 /* The async arg is used to inform this routine it is being called from
  * an async handler process.  It should not hang on a down hard mount.
  */
+
+#ifdef CFS_PAGEVEC
+static int cfs_proc_commit_remote(cfs_mntinfo_t *mip,
+	struct inode *inode, struct cfs_write_data *data);
+#else
+static int cfs_proc_commit_remote(cfs_mntinfo_t *mip,
+	struct inode *inode, loff_t offset, unsigned int count);
+#endif
+
 static int
 #ifdef CFS_PAGEVEC
 cfs_proc_commit(struct cfs_write_data *data)
@@ -1514,28 +1814,11 @@
 		cfs_update_attr(itoc(inode)->c_hp, inode, 1);
 		status = 0;
 	} else {
-		struct cfscommitargs args;
-		struct cfscommitres res;
-
-		args.coma_fhandle = *itocfh(inode);
 #ifdef CFS_PAGEVEC
-		args.coma_offset = data->offset;
-		args.coma_count = data->count;
+		status = cfs_proc_commit_remote(mip, inode, data);
 #else
-		args.coma_offset = offset;
-		args.coma_count = count;
+		status = cfs_proc_commit_remote(mip, inode, offset, count);
 #endif
-
-		status = rcfscall(mip, CFSD_PROC_COMMIT,
-				(xdrproc_t)xdr_cfscommitargs,
-				(caddr_t)&args,
-				(xdrproc_t)xdr_cfscommitres,
-				(caddr_t)&res);
-		if (status == 0) {
-			status = res.comr_status;
-			if (status == 0)
-				cfs_refresh_inode(inode, &res.comr_attr);
-		}
 	}
 
 sb_error_check:
@@ -1551,6 +1834,43 @@
 #endif
 }
 
+static int
+#ifdef CFS_PAGEVEC
+cfs_proc_commit_remote(cfs_mntinfo_t *mip,
+	struct inode *inode, struct cfs_write_data *data)
+#else
+cfs_proc_commit_remote(cfs_mntinfo_t *mip,
+	struct inode *inode, loff_t offset, unsigned int count)
+#endif
+{
+	int status;
+
+	struct cfscommitargs args;
+	struct cfscommitres res;
+
+	args.coma_fhandle = *itocfh(inode);
+#ifdef CFS_PAGEVEC
+	args.coma_offset = data->offset;
+	args.coma_count = data->count;
+#else
+	args.coma_offset = offset;
+	args.coma_count = count;
+#endif
+
+	status = rcfscall(mip, CFSD_PROC_COMMIT,
+			(xdrproc_t)xdr_cfscommitargs,
+			(caddr_t)&args,
+			(xdrproc_t)xdr_cfscommitres,
+			(caddr_t)&res);
+	if (status == 0) {
+		status = res.comr_status;
+		if (status == 0)
+			cfs_refresh_inode(inode, &res.comr_attr);
+	}
+
+	return status;
+}
+
 struct cfs_rpc_ops     cfs_clientops = {
 	.getinode	= cfs_proc_getinode,
 #ifdef CFS_REVALIDATE_GETATTR
Index: kernel/cluster/ssi/cfs/vfs.c
===================================================================
RCS file: /usr/local/lib/cvs-repo/sourceforge-openssi/kernel/cluster/ssi/cfs/vfs.c,v
retrieving revision 1.27
retrieving revision 1.27.4.3
diff -u -r1.27 -r1.27.4.3
--- kernel/cluster/ssi/cfs/vfs.c	10 Oct 2008 08:10:32 -0000	1.27
+++ kernel/cluster/ssi/cfs/vfs.c	15 Jan 2009 14:30:31 -0000	1.27.4.3
@@ -590,13 +590,18 @@
 {
 	mm_segment_t	oldfs;
 	int		err;
-	struct file	file;
+	struct file	*filp;
+
+	if (!(filp = kmalloc (sizeof *filp, GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto out_nomem;
+	}
 
-	err = cfsd_open(hp, S_IFREG, MAY_READ, &file);
+	err = cfsd_open(hp, S_IFREG, MAY_READ, filp);
 	if (err)
 		goto out;
 	err = -EPERM;
-	if (!file.f_op->read)
+	if (!filp->f_op->read)
 		goto out_close;
 
 #ifdef CFS_PARANOIA
@@ -606,20 +611,20 @@
 	/* SSI_XXX: We should send the pid and actually do this mandatory lock
 	 * check.
 	 */
-	ret = locks_verify_area(FLOCK_VERIFY_READ, file.f_dentry->d_inode,
-				&file, file.f_pos, *count);
+	ret = locks_verify_area(FLOCK_VERIFY_READ, filp->f_dentry->d_inode,
+				filp, filp->f_pos, *count);
 #endif
 
 #ifdef CFS_READAHEAD
 	/* Get readahead parameters */
 	if (hp->sct_ra.ra_pages)
-		file.f_ra = hp->sct_ra;
+		filp->f_ra = hp->sct_ra;
 #endif
 
 	oldfs = get_fs(); set_fs(KERNEL_DS);
 #ifdef CFS_PAGEVEC
-	if (file.f_op->readv)
-		err = file.f_op->readv(&file, (struct iovec __user *)vec, vlen, &offset);
+	if (filp->f_op->readv)
+		err = filp->f_op->readv(filp, (struct iovec __user *)vec, vlen, &offset);
 	else {
 		/* Do it by hand, with file-ops. Borrowed from do_readv_writev */
 		err = 0;
@@ -633,7 +638,7 @@
 			vec++;
 			vlen--;
 
-			nr = file.f_op->read(&file, base, len, &offset);
+			nr = filp->f_op->read(filp, base, len, &offset);
 
 			if (nr < 0) {
 				if (!err) err = nr;
@@ -645,26 +650,28 @@
 		}
 	}
 #else
-	file.f_pos = offset;
+	filp->f_pos = offset;
 
-	err = file.f_op->read(&file, buf, *count, &file.f_pos);
+	err = filp->f_op->read(filp, buf, *count, &filp->f_pos);
 #endif
 	set_fs(oldfs);
 
 #ifdef CFS_READAHEAD
 	/* Write back readahead params */
-	hp->sct_ra = file.f_ra;
+	hp->sct_ra = filp->f_ra;
 #endif
 
 	dprintk("cfsd: read complete err=%d\n", err);
 	if (err >= 0) {
 		*count = err;
 		err = 0;
-		dnotify_parent(file.f_dentry, DN_ACCESS);
+		dnotify_parent(filp->f_dentry, DN_ACCESS);
 	}
 out_close:
-	cfsd_close(&file);
+	cfsd_close(filp);
 out:
+	kfree (filp);
+out_nomem:
 	return err;
 }
 
@@ -681,7 +688,7 @@
 	int stable)
 #endif
 {
-	struct file		file;
+	struct file		*filp;
 	struct dentry		*dentry;
 	struct inode		*inode;
 	mm_segment_t		oldfs;
@@ -691,16 +698,21 @@
 	int gathered_writes = 1;
 #endif
 
-	err = cfsd_open(hp, S_IFREG, MAY_WRITE, &file);
+	if (!(filp = kmalloc (sizeof *filp, GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto out_nomem;
+	}
+
+	err = cfsd_open(hp, S_IFREG, MAY_WRITE, filp);
 	if (err)
 		goto out;
 	if (!cnt)
 		goto out_close;
 	err = -EPERM;
-	if (!file.f_op->write)
+	if (!filp->f_op->write)
 		goto out_close;
 
-	dentry = file.f_dentry;
+	dentry = filp->f_dentry;
 	inode = dentry->d_inode;
 
 	/*
@@ -710,7 +722,7 @@
 	 * When gathered writes have been configured for this volume,
 	 * flushing the data to disk is handled separately below.
 	 */
-	if (file.f_op->fsync == 0) {	/* COMMIT cannot work */
+	if (filp->f_op->fsync == 0) {	/* COMMIT cannot work */
 	       stable = 2;
 	}
 
@@ -721,7 +733,7 @@
 #ifdef CFS_GATHERWRITES
 		if (!gathered_writes)
 #endif
-			file.f_flags |= O_SYNC;
+			filp->f_flags |= O_SYNC;
 
 	/* Write the data. */
 	oldfs = get_fs(); set_fs(KERNEL_DS);
@@ -746,23 +758,23 @@
 	 *		...
 	 * ->i_sem	(generic_file_writev)
 	 */
-	if (file.f_op->writev == generic_file_writev && sem_owned(&inode->i_sem)) {
+	if (filp->f_op->writev == generic_file_writev && sem_owned(&inode->i_sem)) {
 		/* Prevent further generic_file_writev() recursion. */
 		current->balancing_dirty_pages = 1;
-		err = generic_file_write_nolock(&file,
+		err = generic_file_write_nolock(filp,
 						(struct iovec __user *)vec,
 						vlen, &offset);
 		current->balancing_dirty_pages = 0;
-	} else if (file.f_op->writev) {
-		err = file.f_op->writev(&file,
+	} else if (filp->f_op->writev) {
+		err = filp->f_op->writev(filp,
 					(struct iovec __user *)vec,
 					vlen, &offset);
 	} else {
-		WARN_ON(file.f_op->write == generic_file_write &&
+		WARN_ON(filp->f_op->write == generic_file_write &&
 				sem_owned(&inode->i_sem));
 #else
-	if (file.f_op->writev)
-		err = file.f_op->writev(&file, (struct iovec __user *)vec, vlen, &offset);
+	if (filp->f_op->writev)
+		err = filp->f_op->writev(filp, (struct iovec __user *)vec, vlen, &offset);
 	else {
 #endif
 		/* Do it by hand, with file-ops. Borrowed from do_readv_writev */
@@ -777,7 +789,7 @@
 			vec++;
 			vlen--;
 
-			nr = file.f_op->write(&file, base, len, &offset);
+			nr = filp->f_op->write(filp, base, len, &offset);
 
 			if (nr < 0) {
 				if (!err) err = nr;
@@ -789,14 +801,14 @@
 		}
 	}
 #else
-	file.f_pos = offset;		/* set write offset */
+	filp->f_pos = offset;		/* set write offset */
 
-	err = file.f_op->write(&file, buf, cnt, &file.f_pos);
+	err = filp->f_op->write(filp, buf, cnt, &filp->f_pos);
 #endif /* !CFS_PAGEVEC */
-	/* err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset); */
+	/* err = vfs_writev(filp, (struct iovec __user *)vec, vlen, &offset); */
 	set_fs(oldfs);
 	if (err > 0)
-		dnotify_parent(file.f_dentry, DN_MODIFY);
+		dnotify_parent(filp->f_dentry, DN_MODIFY);
 
 	/* clear setuid/setgid flag after write */
 	if (err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) {
@@ -851,8 +863,10 @@
 	if (err >= 0)
 		err = 0;
 out_close:
-	cfsd_close(&file);
+	cfsd_close(filp);
 out:
+	kfree (filp);
+out_nomem:
 	return err;
 }