Re: [PATCH 3/3] NFS/localio: nfs_uuid_put() fix the wake up after unlinking the file

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

 



On Wed, 16 Jul 2025, Trond Myklebust wrote:
> From: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx>
> 
> After setting nfl->nfs_uuid to NULL, dereferences of nfl should be
> avoided, since there are no further guarantees that the memory is still
> allocated.

nfl is not being dereferenced here.  The difference between using "nfl"
and "&nfl->nfs_uuid" as the event variable is simply some address
arithmetic.  As long as both are the same it doesn't matter which is
used.


> Also change the wake_up_var_locked() to be a regular wake_up_var(),
> since nfs_close_local_fh() cannot retake the nfs_uuid->lock after
> dropping it.

The point of wake_up_var_locked() is to document why wake_up_var() is
safe.  In general you need a barrier between an assignment and a
wake_up_var().  I would like to eventually remove all wake_up_var()
calls, replacing them with other calls which document why the wakeup is
safe (e.g.  store_release_wake_up(), atomic_dec_and_wake_up()).  In this
case it is safe because both the waker and the waiter hold the same
spinlock.  I would like that documentation to remain.

Also the change from RCU_INIT_POINTER() to rcu_assign_pointer() is not
documented and not needed.  The primary purpose of rcu_assign_pointer()
is to include a barer so that anything that the new value points to will
be visible to a concurrent reader that uses rcu_dereference_pointer().
As NULL doesn't point to anything, no possible barrier is needed and
RCU_INIT_POINTER() is the correct interface to use.

So I think this patch is unnecessary and while it doesn't change
behaviour in any important way, it does make the intention of the code a
little less clear.

Thanks,
NeilBrown


> 
> 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 | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c
> index d157fdc068d7..27ad5263e400 100644
> --- a/fs/nfs_common/nfslocalio.c
> +++ b/fs/nfs_common/nfslocalio.c
> @@ -199,8 +199,8 @@ static bool nfs_uuid_put(nfs_uuid_t *nfs_uuid)
>  		/* Now we can allow racing nfs_close_local_fh() to
>  		 * skip the locking.
>  		 */
> -		RCU_INIT_POINTER(nfl->nfs_uuid, NULL);
> -		wake_up_var_locked(&nfl->nfs_uuid, &nfs_uuid->lock);
> +		rcu_assign_pointer(nfl->nfs_uuid, NULL);
> +		wake_up_var(nfl);
>  	}
>  
>  	/* Remove client from nn->local_clients */
> @@ -321,8 +321,7 @@ void nfs_close_local_fh(struct nfs_file_localio *nfl)
>  		 */
>  		spin_unlock(&nfs_uuid->lock);
>  		rcu_read_unlock();
> -		wait_var_event(&nfl->nfs_uuid,
> -			       rcu_access_pointer(nfl->nfs_uuid) == NULL);
> +		wait_var_event(nfl, rcu_access_pointer(nfl->nfs_uuid) == NULL);
>  		return;
>  	}
>  	/* tell nfs_uuid_put() to wait for us */
> -- 
> 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