[pnfs] [PATCH 4/7] pnfs: fix leak in cl_lo_inodes list

Fred Isaman iisaman at citi.umich.edu
Mon Jun 9 16:29:05 EDT 2008


Remove nfsi from list unconditionally, depite apparent race, since it
is added unconditionally after alloc_init_layout is called.  In
the racy case where nfsi->current_layout == NULL, nfsi is in the
list multiple times, and removal of one instance is correct.

Signed-off-by: Fred Isaman <iisaman at citi.umich.edu>
---
 fs/nfs/pnfs.c |   18 ++++++++----------
 1 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index ea71e9b..52f003d 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -336,7 +336,7 @@ static inline void
 put_unlock_current_layout(struct nfs_inode *nfsi,
 			    struct pnfs_layout_type *lo)
 {
-	struct nfs_client *clp;
+	int destroyed = 0;
 
 	BUG_ON_UNLOCKED_LO(lo);
 	BUG_ON(lo->refcount <= 0);
@@ -349,20 +349,18 @@ put_unlock_current_layout(struct nfs_inode *nfsi,
 		io_ops->free_layout(lo);
 
 		nfsi->current_layout = NULL;
+		destroyed = 1;
+	}
+	spin_unlock(&nfsi->lo_lock);
+
+	if (destroyed) {
+		struct nfs_client *clp;
 
-		/* Unlist the inode.
-		 * Note that nfsi->lo_lock must be released before getting
-		 * cl_sem as the latter can sleep
-		 */
 		clp = NFS_SERVER(&nfsi->vfs_inode)->nfs_client;
-		spin_unlock(&nfsi->lo_lock);
 		down_write(&clp->cl_sem);
-		spin_lock(&nfsi->lo_lock);
-		if (!nfsi->current_layout)
-			list_del_init(&nfsi->lo_inodes);
+		list_del_init(&nfsi->lo_inodes);
 		up_write(&clp->cl_sem);
 	}
-	spin_unlock(&nfsi->lo_lock);
 }
 
 void
-- 
1.5.3.3



More information about the pNFS mailing list