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);