Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 1138

kernel-2.6.18-238.el5.src.rpm

From: Jeff Layton <jlayton@redhat.com>
Date: Fri, 17 Dec 2010 14:05:15 -0500
Subject: [fs] nfs: set lock_context field in nfs_readpage_sync
Message-id: <1292594715-11333-1-git-send-email-jlayton@redhat.com>
Patchwork-id: 30546
O-Subject: [RHEL5.6 PATCH] BZ#663853: nfs: set lock_context field in
	nfs_readpage_sync (try #2)
Bugzilla: 663853
RH-Acked-by: J. Bruce Fields <bfields@redhat.com>

This patch fixes another regression that was introduced with patch
e992fe54 in Jarod's tree. RHEL5 has a nfs_readpage_sync codepath that's
used for synchronous calls, just like the nfs_writepage_sync codepath.
We need to set the lock_context field in it as well in order to prevent
a trivially reproducable oops.

Upstream kernels don't have this function anymore -- it's been merged
with the async codepath.

The original patch came from someone anonymous at Fujitsu, who also
provided the reproducer. That patch was buggy however as it didn't clean
up the refcounts correctly. This patch fixes that problem by moving the
lock context allocation earlier in the function and unifying the error
and non-error exit codepaths.

Signed-off-by: Jeff Layton <jlayton@redhat.com>

diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 7bb2e7c..7a71fc3 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -157,6 +157,12 @@ static int nfs_readpage_sync(struct nfs_open_context *ctx, struct inode *inode,
 		goto out_unlock;
 
 	memset(rdata, 0, sizeof(*rdata));
+
+	rdata->args.lock_context = nfs_get_lock_context(ctx);
+	if (rdata->args.lock_context == NULL) {
+		nfs_readdata_free(rdata);
+		goto out_unlock;
+	}
 	rdata->flags = (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
 	rdata->cred = ctx->cred;
 	rdata->inode = inode;
@@ -219,12 +225,8 @@ static int nfs_readpage_sync(struct nfs_open_context *ctx, struct inode *inode,
 	result = 0;
 
 	nfs_readpage_to_fscache(inode, page, 1);
-	nfs_readdata_release(rdata);
-	unlock_page(page);
-
-	return result;
-
 io_error:
+	nfs_put_lock_context(rdata->args.lock_context);
 	nfs_readdata_release(rdata);
 out_unlock:
 	unlock_page(page);