[PATCH 2/3] NFS/localio: nfs_uuid_put() fix the wait for file unlink events

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

 



From: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx>

No reference to nfl is held when waiting in nfs_uuid_put(), so not only
must the event condition check if the first entry in the list has
changed, it must also check if the nfl->nfs_uuid field is still NULL,
in case the old entry was replaced.

Also change the event variable to be nfs_uuid, for the same reason that
no reference is held to nfl.

Acked-by: Mike Snitzer <snitzer@xxxxxxxxxx>
Tested-by: Mike Snitzer <snitzer@xxxxxxxxxx>
Fixes: 21fb44034695 ("nfs_localio: protect race between nfs_uuid_put() and nfs_close_local_fh()")
Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx>
---
 fs/nfs_common/nfslocalio.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c
index 64949c46c174..d157fdc068d7 100644
--- a/fs/nfs_common/nfslocalio.c
+++ b/fs/nfs_common/nfslocalio.c
@@ -177,12 +177,13 @@ static bool nfs_uuid_put(nfs_uuid_t *nfs_uuid)
 			/* nfs_close_local_fh() is doing the
 			 * close and we must wait. until it unlinks
 			 */
-			wait_var_event_spinlock(nfl,
-						list_first_entry_or_null(
-							&nfs_uuid->files,
-							struct nfs_file_localio,
-							list) != nfl,
-						&nfs_uuid->lock);
+			wait_var_event_spinlock(
+				nfs_uuid,
+				list_first_entry_or_null(
+					&nfs_uuid->files,
+					struct nfs_file_localio, list) != nfl ||
+					rcu_access_pointer(nfl->nfs_uuid),
+				&nfs_uuid->lock);
 			continue;
 		}
 
@@ -338,7 +339,7 @@ void nfs_close_local_fh(struct nfs_file_localio *nfl)
 	 */
 	spin_lock(&nfs_uuid->lock);
 	list_del_init(&nfl->list);
-	wake_up_var_locked(&nfl->nfs_uuid, &nfs_uuid->lock);
+	wake_up_var_locked(nfs_uuid, &nfs_uuid->lock);
 	spin_unlock(&nfs_uuid->lock);
 }
 EXPORT_SYMBOL_GPL(nfs_close_local_fh);
-- 
2.50.1





[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