[PATCH 2/3] nfsd: fix potential race in nfsd_file_close

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Once we call nfsd_file_put, there is no guarantee that "nf" can still be
safely accessed. That may have been the last reference.

Change the code to instead check for whether nf_ref is 2 and then unhash
it and put the reference if we're successful.

We might occasionally race with another lookup and end up unhashing it
when it probably shouldn't have been, but that should hopefully be rare
and will just result in the competing lookup having to create a new
nfsd_file.

Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
---
 fs/nfsd/filecache.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c
index 6237715bd23e..58f4d9267f4a 100644
--- a/fs/nfsd/filecache.c
+++ b/fs/nfsd/filecache.c
@@ -461,12 +461,14 @@ nfsd_file_put(struct nfsd_file *nf)
  */
 void nfsd_file_close(struct nfsd_file *nf)
 {
-	nfsd_file_put(nf);
-	if (refcount_dec_if_one(&nf->nf_ref)) {
-		nfsd_file_unhash(nf);
-		nfsd_file_lru_remove(nf);
-		nfsd_file_free(nf);
+	/* One for the reference being put, and one for the hash */
+	if (refcount_read(&nf->nf_ref) == 2) {
+		if (nfsd_file_unhash(nf))
+			nfsd_file_put_noref(nf);
 	}
+	/* put the ref for the stateid */
+	nfsd_file_put(nf);
+
 }
 
 struct nfsd_file *
-- 
2.37.3




[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux