[ewg] [PATCH OFED-1.5] NFSRDMA: Fix page leak

Jon Mason jon at opengridcomputing.com
Thu Jun 11 14:19:30 PDT 2009


In the conversion from splice_direct_to_actor to sendfile, the callback
routine was converted to the previous version without reference to the
new changes to the callback route that calls the put_page.  Previously,
it had been called in svc_release_buffer, but due to significant changes
in the logic of that function it cannot be done there.

Similar fixes for RHEL5 have been included in the patches submitted for
inclusion.
    
Signed-Off-By: Jon Mason <jon at opengridcomputing.com>

diff --git a/kernel_patches/backport/2.6.22/rnfs_fs.patch b/kernel_patches/backport/2.6.22/rnfs_fs.patch
index 8e1e0b2..ebe9a6c 100644
--- a/kernel_patches/backport/2.6.22/rnfs_fs.patch
+++ b/kernel_patches/backport/2.6.22/rnfs_fs.patch
@@ -961,7 +961,7 @@ index 9f1ca17..3702de6 100644
  		error = nfsd_setuser_and_check_port(rqstp, exp);
  		if (error)
 diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
-index 6c68ffd..5e76f84 100644
+index 6c68ffd..0ec6707 100644
 --- a/fs/nfsd/vfs.c
 +++ b/fs/nfsd/vfs.c
 @@ -55,6 +55,7 @@
@@ -989,7 +989,7 @@ index 6c68ffd..5e76f84 100644
  	if (IS_ERR(*filp))
  		host_err = PTR_ERR(*filp);
  out_nfserr:
-@@ -843,45 +843,30 @@ found:
+@@ -843,47 +843,38 @@ found:
   * directly. They will be released after the sending has completed.
   */
  static int
@@ -998,7 +998,9 @@ index 6c68ffd..5e76f84 100644
 +nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset, unsigned long size)
  {
 -	struct svc_rqst *rqstp = sd->u.data;
--	struct page **pp = rqstp->rq_respages + rqstp->rq_resused;
++	unsigned long count = desc->count;
++	struct svc_rqst *rqstp = desc->arg.data;
+ 	struct page **pp = rqstp->rq_respages + rqstp->rq_resused;
 -	struct page *page = buf->page;
 -	size_t size;
 -	int ret;
@@ -1006,8 +1008,6 @@ index 6c68ffd..5e76f84 100644
 -	ret = buf->ops->confirm(pipe, buf);
 -	if (unlikely(ret))
 -		return ret;
-+	unsigned long count = desc->count;
-+	struct svc_rqst *rqstp = desc->arg.data;
  
 -	size = sd->len;
 +	if (size > count)
@@ -1019,35 +1019,40 @@ index 6c68ffd..5e76f84 100644
 -		*pp = page;
 -		rqstp->rq_resused++;
 -		rqstp->rq_res.page_base = buf->offset;
++		if (*pp)
++			put_page(*pp);
 +		rqstp->rq_respages[rqstp->rq_resused++] = page;
 +		rqstp->rq_res.page_base = offset;
  		rqstp->rq_res.page_len = size;
 -	} else if (page != pp[-1]) {
-+	} else if (page != rqstp->rq_respages[rqstp->rq_resused-1]) { 
++	} else if (page != rqstp->rq_respages[rqstp->rq_resused-1]) {
  		get_page(page);
--		if (*pp)
--			put_page(*pp);
--		*pp = page;
+ 		if (*pp)
+ 			put_page(*pp);
+ 		*pp = page;
 -		rqstp->rq_resused++;
 +		rqstp->rq_respages[rqstp->rq_resused++] = page;
  		rqstp->rq_res.page_len += size;
- 	} else
+-	} else
++	} else {
  		rqstp->rq_res.page_len += size;
++	}
  
--	return size;
--}
 +	desc->count = count - size;
 +	desc->written += size;
+ 	return size;
+ }
  
 -static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
 -				    struct splice_desc *sd)
 -{
 -	return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
-+	return size;
- }
- 
+-}
+-
  static inline int svc_msnfs(struct svc_fh *ffhp)
-@@ -915,16 +900,9 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
+ {
+ #ifdef MSNFS
+@@ -915,16 +906,9 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
  	if (ra && ra->p_set)
  		file->f_ra = ra->p_ra;
  
@@ -1066,7 +1071,7 @@ index 6c68ffd..5e76f84 100644
  	} else {
  		oldfs = get_fs();
  		set_fs(KERNEL_DS);
-@@ -1005,9 +983,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
+@@ -1005,9 +989,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
  	if (!EX_ISSYNC(exp))
  		stable = 0;
  	if (stable && !EX_WGATHER(exp)) {



More information about the ewg mailing list