aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@primarydata.com>2014-08-22 12:26:36 -0400
committerJeff Layton <jlayton@primarydata.com>2014-10-07 14:06:12 -0400
commit415b96c5a1fe31ed9deb0618e95ecbb1df3de54c (patch)
treebe4fbf6503911abac9a71fc0856c3e7a9b27e221 /fs/nfsd/nfs4state.c
parentbfe8602436c803c6d5e271d52cd985d491a7470a (diff)
nfsd: fix potential lease memory leak in nfs4_setlease
It's unlikely to ever occur, but if there were already a lease set on the file then we could end up getting back a different pointer on a successful setlease attempt than the one we allocated. If that happens, the one we allocated could leak. In practice, I don't think this will happen due to the fact that we only try to set up the lease once per nfs4_file, but this error handling is a bit more correct given the current lease API. Cc: J. Bruce Fields <bfields@fieldses.org> Signed-off-by: Jeff Layton <jlayton@primarydata.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index a91e521622c3..5bb4952faf5b 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -3781,7 +3781,7 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_file *fp, int flag)
3781static int nfs4_setlease(struct nfs4_delegation *dp) 3781static int nfs4_setlease(struct nfs4_delegation *dp)
3782{ 3782{
3783 struct nfs4_file *fp = dp->dl_stid.sc_file; 3783 struct nfs4_file *fp = dp->dl_stid.sc_file;
3784 struct file_lock *fl; 3784 struct file_lock *fl, *ret;
3785 struct file *filp; 3785 struct file *filp;
3786 int status = 0; 3786 int status = 0;
3787 3787
@@ -3795,11 +3795,14 @@ static int nfs4_setlease(struct nfs4_delegation *dp)
3795 return -EBADF; 3795 return -EBADF;
3796 } 3796 }
3797 fl->fl_file = filp; 3797 fl->fl_file = filp;
3798 status = vfs_setlease(filp, fl->fl_type, &fl); 3798 ret = fl;
3799 status = vfs_setlease(filp, fl->fl_type, &ret);
3799 if (status) { 3800 if (status) {
3800 locks_free_lock(fl); 3801 locks_free_lock(fl);
3801 goto out_fput; 3802 goto out_fput;
3802 } 3803 }
3804 if (ret != fl)
3805 locks_free_lock(fl);
3803 spin_lock(&state_lock); 3806 spin_lock(&state_lock);
3804 spin_lock(&fp->fi_lock); 3807 spin_lock(&fp->fi_lock);
3805 /* Did the lease get broken before we took the lock? */ 3808 /* Did the lease get broken before we took the lock? */