This is a note to let you know that I've just added the patch titled
nfsd4: fix struct file leak
to the 2.6.37-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
nfsd4-fix-struct-file-leak.patch
and it can be found in the queue-2.6.37 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <[email protected]> know about it.
From 0997b173609b9229ece28941c118a2a9b278796e Mon Sep 17 00:00:00 2001
From: J. Bruce Fields <[email protected]>
Date: Wed, 2 Mar 2011 18:01:35 -0500
Subject: nfsd4: fix struct file leak
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: J. Bruce Fields <[email protected]>
commit 0997b173609b9229ece28941c118a2a9b278796e upstream.
Make sure we properly reference count the struct files that a lock
depends on, and release them when the lock stateid is released.
This fixes a major leak of struct files when using locking over nfsv4.
Reported-by: Rick Koshi <[email protected]>
Tested-by: Ivo Přikryl <[email protected]>
Signed-off-by: J. Bruce Fields <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/nfsd/nfs4state.c | 32 +++++++++++++++++++++-----------
1 file changed, 21 insertions(+), 11 deletions(-)
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -408,6 +408,9 @@ static void unhash_generic_stateid(struc
static void free_generic_stateid(struct nfs4_stateid *stp)
{
+ int oflag = nfs4_access_bmap_to_omode(stp);
+
+ nfs4_file_put_access(stp->st_file, oflag);
put_nfs4_file(stp->st_file);
kmem_cache_free(stateid_slab, stp);
}
@@ -459,11 +462,8 @@ release_stateid_lockowners(struct nfs4_s
static void release_open_stateid(struct nfs4_stateid *stp)
{
- int oflag = nfs4_access_bmap_to_omode(stp);
-
unhash_generic_stateid(stp);
release_stateid_lockowners(stp);
- nfs4_file_put_access(stp->st_file, oflag);
free_generic_stateid(stp);
}
@@ -3661,6 +3661,7 @@ alloc_init_lock_stateid(struct nfs4_stat
stp->st_stateid.si_stateownerid = sop->so_id;
stp->st_stateid.si_fileid = fp->fi_id;
stp->st_stateid.si_generation = 0;
+ stp->st_access_bmap = 0;
stp->st_deny_bmap = open_stp->st_deny_bmap;
stp->st_openstp = open_stp;
@@ -3675,6 +3676,17 @@ check_lock_length(u64 offset, u64 length
LOFF_OVERFLOW(offset, length)));
}
+static void get_lock_access(struct nfs4_stateid *lock_stp, u32 access)
+{
+ struct nfs4_file *fp = lock_stp->st_file;
+ int oflag = nfs4_access_to_omode(access);
+
+ if (test_bit(access, &lock_stp->st_access_bmap))
+ return;
+ nfs4_file_get_access(fp, oflag);
+ __set_bit(access, &lock_stp->st_access_bmap);
+}
+
/*
* LOCK operation
*/
@@ -3772,18 +3784,16 @@ nfsd4_lock(struct svc_rqst *rqstp, struc
switch (lock->lk_type) {
case NFS4_READ_LT:
case NFS4_READW_LT:
- if (find_readable_file(lock_stp->st_file)) {
- nfs4_get_vfs_file(rqstp, fp,
&cstate->current_fh, NFS4_SHARE_ACCESS_READ);
- filp = find_readable_file(lock_stp->st_file);
- }
+ filp = find_readable_file(lock_stp->st_file);
+ if (filp)
+ get_lock_access(lock_stp,
NFS4_SHARE_ACCESS_READ);
file_lock.fl_type = F_RDLCK;
break;
case NFS4_WRITE_LT:
case NFS4_WRITEW_LT:
- if (find_writeable_file(lock_stp->st_file)) {
- nfs4_get_vfs_file(rqstp, fp,
&cstate->current_fh, NFS4_SHARE_ACCESS_WRITE);
- filp = find_writeable_file(lock_stp->st_file);
- }
+ filp = find_writeable_file(lock_stp->st_file);
+ if (filp)
+ get_lock_access(lock_stp,
NFS4_SHARE_ACCESS_WRITE);
file_lock.fl_type = F_WRLCK;
break;
default:
Patches currently in stable-queue which might be from [email protected] are
queue-2.6.37/nfsd4-minor-nfs4state.c-reshuffling.patch
queue-2.6.37/nfsd4-fix-struct-file-leak.patch
queue-2.6.37/nfsd41-modify-the-members-value-of-nfsd4_op_flags.patch
queue-2.6.37/nfsd-wrong-index-used-in-inner-loop.patch
_______________________________________________
stable mailing list
[email protected]
http://linux.kernel.org/mailman/listinfo/stable