[v2,1/2] nfsd: wake waiters blocked on file_lock before deleting it
diff mbox series

Message ID 20190422163424.19402-2-jlayton@kernel.org
State New
Headers show
Series
  • nfsd: ensure we wake file lock waiters before deleting blocked lock
Related show

Commit Message

Jeff Layton April 22, 2019, 4:34 p.m. UTC
After a blocked nfsd file_lock request is deleted, knfsd will send a
callback to the client and then free the request. Commit 16306a61d3b7
("fs/locks: always delete_block after waiting.") changed it such that
locks_delete_block is always called on a request after it is awoken,
but that patch missed fixing up blocked nfsd request handling.

Call locks_delete_block on the block to wake up any locks still blocked
on the nfsd lock request before freeing it. Some of its callers already
do this however, so just remove those calls.

URL: https://bugzilla.kernel.org/show_bug.cgi?id=203363
Fixes: 16306a61d3b7 ("fs/locks: always delete_block after waiting.")
Reported-by: Slawomir Pryczek <slawek1211@gmail.com>
Cc: Neil Brown <neilb@suse.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 fs/nfsd/nfs4state.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

Comments

NeilBrown April 22, 2019, 11:47 p.m. UTC | #1
On Mon, Apr 22 2019, Jeff Layton wrote:

> After a blocked nfsd file_lock request is deleted, knfsd will send a
> callback to the client and then free the request. Commit 16306a61d3b7
> ("fs/locks: always delete_block after waiting.") changed it such that
> locks_delete_block is always called on a request after it is awoken,
> but that patch missed fixing up blocked nfsd request handling.
>
> Call locks_delete_block on the block to wake up any locks still blocked
> on the nfsd lock request before freeing it. Some of its callers already
> do this however, so just remove those calls.
>
> URL: https://bugzilla.kernel.org/show_bug.cgi?id=203363
> Fixes: 16306a61d3b7 ("fs/locks: always delete_block after waiting.")
> Reported-by: Slawomir Pryczek <slawek1211@gmail.com>
> Cc: Neil Brown <neilb@suse.com>
> Cc: stable@vger.kernel.org
> Signed-off-by: Jeff Layton <jlayton@kernel.org>
> ---
>  fs/nfsd/nfs4state.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> index 6a45fb00c5fc..e87e15df2044 100644
> --- a/fs/nfsd/nfs4state.c
> +++ b/fs/nfsd/nfs4state.c
> @@ -265,6 +265,7 @@ find_or_allocate_block(struct nfs4_lockowner *lo, struct knfsd_fh *fh,
>  static void
>  free_blocked_lock(struct nfsd4_blocked_lock *nbl)
>  {
> +	locks_delete_block(&nbl->nbl_lock);
>  	locks_release_private(&nbl->nbl_lock);

Thanks for tracking this down.

An implication of this bug and fix is that we need to be particularly
careful to make sure locks_delete_block() is called on all relevant
paths.
Can we make that easier?  My first thought was to include the call in
locks_release_private, but lockd calls the two quite separately and it
certainly seems appropriate that locks_delete_block should be called
asap, but locks_release_private() can be delayed.

Also cifs calls locks_delete_block, but never calls
locks_release_private, so it wouldn't help there.

Looking at cifs, I think there is a call missing there too.
cifs_posix_lock_set() *doesn't* always call locks_delete_block() after
waiting.  In particular, if ->can_cache_brlcks becomes true while
waiting then I don't think the behaviour is right.... though I'm not
sure it is right for other reasons.  It looks like the return value
should be 1 in that case, but it'll be zero.

But back to my question about making it easier, move the BUG_ON()
calls from locks_free_lock() into locks_release_private().

??

Thanks,
NeilBrown


>  	kfree(nbl);
>  }
> @@ -293,7 +294,6 @@ remove_blocked_locks(struct nfs4_lockowner *lo)
>  		nbl = list_first_entry(&reaplist, struct nfsd4_blocked_lock,
>  					nbl_lru);
>  		list_del_init(&nbl->nbl_lru);
> -		locks_delete_block(&nbl->nbl_lock);
>  		free_blocked_lock(nbl);
>  	}
>  }
> @@ -4863,7 +4863,6 @@ nfs4_laundromat(struct nfsd_net *nn)
>  		nbl = list_first_entry(&reaplist,
>  					struct nfsd4_blocked_lock, nbl_lru);
>  		list_del_init(&nbl->nbl_lru);
> -		locks_delete_block(&nbl->nbl_lock);
>  		free_blocked_lock(nbl);
>  	}
>  out:
> -- 
> 2.20.1
Jeff Layton April 23, 2019, 10:57 a.m. UTC | #2
On Mon, Apr 22, 2019 at 7:47 PM NeilBrown <neilb@suse.com> wrote:
>
> On Mon, Apr 22 2019, Jeff Layton wrote:
>
> > After a blocked nfsd file_lock request is deleted, knfsd will send a
> > callback to the client and then free the request. Commit 16306a61d3b7
> > ("fs/locks: always delete_block after waiting.") changed it such that
> > locks_delete_block is always called on a request after it is awoken,
> > but that patch missed fixing up blocked nfsd request handling.
> >
> > Call locks_delete_block on the block to wake up any locks still blocked
> > on the nfsd lock request before freeing it. Some of its callers already
> > do this however, so just remove those calls.
> >
> > URL: https://bugzilla.kernel.org/show_bug.cgi?id=203363
> > Fixes: 16306a61d3b7 ("fs/locks: always delete_block after waiting.")
> > Reported-by: Slawomir Pryczek <slawek1211@gmail.com>
> > Cc: Neil Brown <neilb@suse.com>
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Jeff Layton <jlayton@kernel.org>
> > ---
> >  fs/nfsd/nfs4state.c | 3 +--
> >  1 file changed, 1 insertion(+), 2 deletions(-)
> >
> > diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> > index 6a45fb00c5fc..e87e15df2044 100644
> > --- a/fs/nfsd/nfs4state.c
> > +++ b/fs/nfsd/nfs4state.c
> > @@ -265,6 +265,7 @@ find_or_allocate_block(struct nfs4_lockowner *lo, struct knfsd_fh *fh,
> >  static void
> >  free_blocked_lock(struct nfsd4_blocked_lock *nbl)
> >  {
> > +     locks_delete_block(&nbl->nbl_lock);
> >       locks_release_private(&nbl->nbl_lock);
>
> Thanks for tracking this down.
>
> An implication of this bug and fix is that we need to be particularly
> careful to make sure locks_delete_block() is called on all relevant
> paths.
> Can we make that easier?  My first thought was to include the call in
> locks_release_private, but lockd calls the two quite separately and it
> certainly seems appropriate that locks_delete_block should be called
> asap, but locks_release_private() can be delayed.
>
> Also cifs calls locks_delete_block, but never calls
> locks_release_private, so it wouldn't help there.
>
> Looking at cifs, I think there is a call missing there too.
> cifs_posix_lock_set() *doesn't* always call locks_delete_block() after
> waiting.  In particular, if ->can_cache_brlcks becomes true while
> waiting then I don't think the behaviour is right.... though I'm not
> sure it is right for other reasons.  It looks like the return value
> should be 1 in that case, but it'll be zero.
>
> But back to my question about making it easier, move the BUG_ON()
> calls from locks_free_lock() into locks_release_private().
>
> ??
>

That sounds like a fine idea. I was thinking about putting all of the
BUG_ONs there in a separate function that both spots could call, but
moving them into locks_release_private should work just as well. Care
to propose a patch?
--
Jeff Layton <jlayton@kernel.org>
J. Bruce Fields April 24, 2019, 1:58 p.m. UTC | #3
Steve, see Neil's comment, is there a cifs bug here?

--b.

On Tue, Apr 23, 2019 at 09:47:06AM +1000, NeilBrown wrote:
> On Mon, Apr 22 2019, Jeff Layton wrote:
> 
> > After a blocked nfsd file_lock request is deleted, knfsd will send a
> > callback to the client and then free the request. Commit 16306a61d3b7
> > ("fs/locks: always delete_block after waiting.") changed it such that
> > locks_delete_block is always called on a request after it is awoken,
> > but that patch missed fixing up blocked nfsd request handling.
> >
> > Call locks_delete_block on the block to wake up any locks still blocked
> > on the nfsd lock request before freeing it. Some of its callers already
> > do this however, so just remove those calls.
> >
> > URL: https://bugzilla.kernel.org/show_bug.cgi?id=203363
> > Fixes: 16306a61d3b7 ("fs/locks: always delete_block after waiting.")
> > Reported-by: Slawomir Pryczek <slawek1211@gmail.com>
> > Cc: Neil Brown <neilb@suse.com>
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Jeff Layton <jlayton@kernel.org>
> > ---
> >  fs/nfsd/nfs4state.c | 3 +--
> >  1 file changed, 1 insertion(+), 2 deletions(-)
> >
> > diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> > index 6a45fb00c5fc..e87e15df2044 100644
> > --- a/fs/nfsd/nfs4state.c
> > +++ b/fs/nfsd/nfs4state.c
> > @@ -265,6 +265,7 @@ find_or_allocate_block(struct nfs4_lockowner *lo, struct knfsd_fh *fh,
> >  static void
> >  free_blocked_lock(struct nfsd4_blocked_lock *nbl)
> >  {
> > +	locks_delete_block(&nbl->nbl_lock);
> >  	locks_release_private(&nbl->nbl_lock);
> 
> Thanks for tracking this down.
> 
> An implication of this bug and fix is that we need to be particularly
> careful to make sure locks_delete_block() is called on all relevant
> paths.
> Can we make that easier?  My first thought was to include the call in
> locks_release_private, but lockd calls the two quite separately and it
> certainly seems appropriate that locks_delete_block should be called
> asap, but locks_release_private() can be delayed.
> 
> Also cifs calls locks_delete_block, but never calls
> locks_release_private, so it wouldn't help there.
> 
> Looking at cifs, I think there is a call missing there too.
> cifs_posix_lock_set() *doesn't* always call locks_delete_block() after
> waiting.  In particular, if ->can_cache_brlcks becomes true while
> waiting then I don't think the behaviour is right.... though I'm not
> sure it is right for other reasons.  It looks like the return value
> should be 1 in that case, but it'll be zero.
> 
> But back to my question about making it easier, move the BUG_ON()
> calls from locks_free_lock() into locks_release_private().
> 
> ??
> 
> Thanks,
> NeilBrown
> 
> 
> >  	kfree(nbl);
> >  }
> > @@ -293,7 +294,6 @@ remove_blocked_locks(struct nfs4_lockowner *lo)
> >  		nbl = list_first_entry(&reaplist, struct nfsd4_blocked_lock,
> >  					nbl_lru);
> >  		list_del_init(&nbl->nbl_lru);
> > -		locks_delete_block(&nbl->nbl_lock);
> >  		free_blocked_lock(nbl);
> >  	}
> >  }
> > @@ -4863,7 +4863,6 @@ nfs4_laundromat(struct nfsd_net *nn)
> >  		nbl = list_first_entry(&reaplist,
> >  					struct nfsd4_blocked_lock, nbl_lru);
> >  		list_del_init(&nbl->nbl_lru);
> > -		locks_delete_block(&nbl->nbl_lock);
> >  		free_blocked_lock(nbl);
> >  	}
> >  out:
> > -- 
> > 2.20.1
Steve Dickson April 24, 2019, 3:29 p.m. UTC | #4
On 4/24/19 9:58 AM, J. Bruce Fields wrote:
> Steve, see Neil's comment, is there a cifs bug here?
Looking into it... 

steved.
> 
> --b.
> 
> On Tue, Apr 23, 2019 at 09:47:06AM +1000, NeilBrown wrote:
>> On Mon, Apr 22 2019, Jeff Layton wrote:
>>
>>> After a blocked nfsd file_lock request is deleted, knfsd will send a
>>> callback to the client and then free the request. Commit 16306a61d3b7
>>> ("fs/locks: always delete_block after waiting.") changed it such that
>>> locks_delete_block is always called on a request after it is awoken,
>>> but that patch missed fixing up blocked nfsd request handling.
>>>
>>> Call locks_delete_block on the block to wake up any locks still blocked
>>> on the nfsd lock request before freeing it. Some of its callers already
>>> do this however, so just remove those calls.
>>>
>>> URL: https://bugzilla.kernel.org/show_bug.cgi?id=203363
>>> Fixes: 16306a61d3b7 ("fs/locks: always delete_block after waiting.")
>>> Reported-by: Slawomir Pryczek <slawek1211@gmail.com>
>>> Cc: Neil Brown <neilb@suse.com>
>>> Cc: stable@vger.kernel.org
>>> Signed-off-by: Jeff Layton <jlayton@kernel.org>
>>> ---
>>>  fs/nfsd/nfs4state.c | 3 +--
>>>  1 file changed, 1 insertion(+), 2 deletions(-)
>>>
>>> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
>>> index 6a45fb00c5fc..e87e15df2044 100644
>>> --- a/fs/nfsd/nfs4state.c
>>> +++ b/fs/nfsd/nfs4state.c
>>> @@ -265,6 +265,7 @@ find_or_allocate_block(struct nfs4_lockowner *lo, struct knfsd_fh *fh,
>>>  static void
>>>  free_blocked_lock(struct nfsd4_blocked_lock *nbl)
>>>  {
>>> +	locks_delete_block(&nbl->nbl_lock);
>>>  	locks_release_private(&nbl->nbl_lock);
>>
>> Thanks for tracking this down.
>>
>> An implication of this bug and fix is that we need to be particularly
>> careful to make sure locks_delete_block() is called on all relevant
>> paths.
>> Can we make that easier?  My first thought was to include the call in
>> locks_release_private, but lockd calls the two quite separately and it
>> certainly seems appropriate that locks_delete_block should be called
>> asap, but locks_release_private() can be delayed.
>>
>> Also cifs calls locks_delete_block, but never calls
>> locks_release_private, so it wouldn't help there.
>>
>> Looking at cifs, I think there is a call missing there too.
>> cifs_posix_lock_set() *doesn't* always call locks_delete_block() after
>> waiting.  In particular, if ->can_cache_brlcks becomes true while
>> waiting then I don't think the behaviour is right.... though I'm not
>> sure it is right for other reasons.  It looks like the return value
>> should be 1 in that case, but it'll be zero.
>>
>> But back to my question about making it easier, move the BUG_ON()
>> calls from locks_free_lock() into locks_release_private().
>>
>> ??
>>
>> Thanks,
>> NeilBrown
>>
>>
>>>  	kfree(nbl);
>>>  }
>>> @@ -293,7 +294,6 @@ remove_blocked_locks(struct nfs4_lockowner *lo)
>>>  		nbl = list_first_entry(&reaplist, struct nfsd4_blocked_lock,
>>>  					nbl_lru);
>>>  		list_del_init(&nbl->nbl_lru);
>>> -		locks_delete_block(&nbl->nbl_lock);
>>>  		free_blocked_lock(nbl);
>>>  	}
>>>  }
>>> @@ -4863,7 +4863,6 @@ nfs4_laundromat(struct nfsd_net *nn)
>>>  		nbl = list_first_entry(&reaplist,
>>>  					struct nfsd4_blocked_lock, nbl_lru);
>>>  		list_del_init(&nbl->nbl_lru);
>>> -		locks_delete_block(&nbl->nbl_lock);
>>>  		free_blocked_lock(nbl);
>>>  	}
>>>  out:
>>> -- 
>>> 2.20.1
> 
>
J. Bruce Fields April 24, 2019, 3:47 p.m. UTC | #5
On Wed, Apr 24, 2019 at 11:29:59AM -0400, Steve Dickson wrote:
> 
> 
> On 4/24/19 9:58 AM, J. Bruce Fields wrote:
> > Steve, see Neil's comment, is there a cifs bug here?
> Looking into it... 

I was thinking Steve French, though I'm sure he wouldn't mind if you
fixed cifs bugs.  Too many Steves!

--b.

> 
> steved.
> > 
> > --b.
> > 
> > On Tue, Apr 23, 2019 at 09:47:06AM +1000, NeilBrown wrote:
> >> On Mon, Apr 22 2019, Jeff Layton wrote:
> >>
> >>> After a blocked nfsd file_lock request is deleted, knfsd will send a
> >>> callback to the client and then free the request. Commit 16306a61d3b7
> >>> ("fs/locks: always delete_block after waiting.") changed it such that
> >>> locks_delete_block is always called on a request after it is awoken,
> >>> but that patch missed fixing up blocked nfsd request handling.
> >>>
> >>> Call locks_delete_block on the block to wake up any locks still blocked
> >>> on the nfsd lock request before freeing it. Some of its callers already
> >>> do this however, so just remove those calls.
> >>>
> >>> URL: https://bugzilla.kernel.org/show_bug.cgi?id=203363
> >>> Fixes: 16306a61d3b7 ("fs/locks: always delete_block after waiting.")
> >>> Reported-by: Slawomir Pryczek <slawek1211@gmail.com>
> >>> Cc: Neil Brown <neilb@suse.com>
> >>> Cc: stable@vger.kernel.org
> >>> Signed-off-by: Jeff Layton <jlayton@kernel.org>
> >>> ---
> >>>  fs/nfsd/nfs4state.c | 3 +--
> >>>  1 file changed, 1 insertion(+), 2 deletions(-)
> >>>
> >>> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> >>> index 6a45fb00c5fc..e87e15df2044 100644
> >>> --- a/fs/nfsd/nfs4state.c
> >>> +++ b/fs/nfsd/nfs4state.c
> >>> @@ -265,6 +265,7 @@ find_or_allocate_block(struct nfs4_lockowner *lo, struct knfsd_fh *fh,
> >>>  static void
> >>>  free_blocked_lock(struct nfsd4_blocked_lock *nbl)
> >>>  {
> >>> +	locks_delete_block(&nbl->nbl_lock);
> >>>  	locks_release_private(&nbl->nbl_lock);
> >>
> >> Thanks for tracking this down.
> >>
> >> An implication of this bug and fix is that we need to be particularly
> >> careful to make sure locks_delete_block() is called on all relevant
> >> paths.
> >> Can we make that easier?  My first thought was to include the call in
> >> locks_release_private, but lockd calls the two quite separately and it
> >> certainly seems appropriate that locks_delete_block should be called
> >> asap, but locks_release_private() can be delayed.
> >>
> >> Also cifs calls locks_delete_block, but never calls
> >> locks_release_private, so it wouldn't help there.
> >>
> >> Looking at cifs, I think there is a call missing there too.
> >> cifs_posix_lock_set() *doesn't* always call locks_delete_block() after
> >> waiting.  In particular, if ->can_cache_brlcks becomes true while
> >> waiting then I don't think the behaviour is right.... though I'm not
> >> sure it is right for other reasons.  It looks like the return value
> >> should be 1 in that case, but it'll be zero.
> >>
> >> But back to my question about making it easier, move the BUG_ON()
> >> calls from locks_free_lock() into locks_release_private().
> >>
> >> ??
> >>
> >> Thanks,
> >> NeilBrown
> >>
> >>
> >>>  	kfree(nbl);
> >>>  }
> >>> @@ -293,7 +294,6 @@ remove_blocked_locks(struct nfs4_lockowner *lo)
> >>>  		nbl = list_first_entry(&reaplist, struct nfsd4_blocked_lock,
> >>>  					nbl_lru);
> >>>  		list_del_init(&nbl->nbl_lru);
> >>> -		locks_delete_block(&nbl->nbl_lock);
> >>>  		free_blocked_lock(nbl);
> >>>  	}
> >>>  }
> >>> @@ -4863,7 +4863,6 @@ nfs4_laundromat(struct nfsd_net *nn)
> >>>  		nbl = list_first_entry(&reaplist,
> >>>  					struct nfsd4_blocked_lock, nbl_lru);
> >>>  		list_del_init(&nbl->nbl_lru);
> >>> -		locks_delete_block(&nbl->nbl_lock);
> >>>  		free_blocked_lock(nbl);
> >>>  	}
> >>>  out:
> >>> -- 
> >>> 2.20.1
> > 
> >
Pavel Shilovsky April 24, 2019, 7:09 p.m. UTC | #6
Yes, I think there is a bug here, thanks!

If cinode->can_cache_brlcks is false we should return 1 but the code
will return 0 if coming from the "try_again" label. We also need to
call locks_delete_block unconditionally at the end of the function.

--
Best regards,
Pavel Shilovsky

ср, 24 апр. 2019 г. в 08:48, J. Bruce Fields <bfields@fieldses.org>:
>
> On Wed, Apr 24, 2019 at 11:29:59AM -0400, Steve Dickson wrote:
> >
> >
> > On 4/24/19 9:58 AM, J. Bruce Fields wrote:
> > > Steve, see Neil's comment, is there a cifs bug here?
> > Looking into it...
>
> I was thinking Steve French, though I'm sure he wouldn't mind if you
> fixed cifs bugs.  Too many Steves!
>
> --b.
>
> >
> > steved.
> > >
> > > --b.
> > >
> > > On Tue, Apr 23, 2019 at 09:47:06AM +1000, NeilBrown wrote:
> > >> On Mon, Apr 22 2019, Jeff Layton wrote:
> > >>
> > >>> After a blocked nfsd file_lock request is deleted, knfsd will send a
> > >>> callback to the client and then free the request. Commit 16306a61d3b7
> > >>> ("fs/locks: always delete_block after waiting.") changed it such that
> > >>> locks_delete_block is always called on a request after it is awoken,
> > >>> but that patch missed fixing up blocked nfsd request handling.
> > >>>
> > >>> Call locks_delete_block on the block to wake up any locks still blocked
> > >>> on the nfsd lock request before freeing it. Some of its callers already
> > >>> do this however, so just remove those calls.
> > >>>
> > >>> URL: https://bugzilla.kernel.org/show_bug.cgi?id=203363
> > >>> Fixes: 16306a61d3b7 ("fs/locks: always delete_block after waiting.")
> > >>> Reported-by: Slawomir Pryczek <slawek1211@gmail.com>
> > >>> Cc: Neil Brown <neilb@suse.com>
> > >>> Cc: stable@vger.kernel.org
> > >>> Signed-off-by: Jeff Layton <jlayton@kernel.org>
> > >>> ---
> > >>>  fs/nfsd/nfs4state.c | 3 +--
> > >>>  1 file changed, 1 insertion(+), 2 deletions(-)
> > >>>
> > >>> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> > >>> index 6a45fb00c5fc..e87e15df2044 100644
> > >>> --- a/fs/nfsd/nfs4state.c
> > >>> +++ b/fs/nfsd/nfs4state.c
> > >>> @@ -265,6 +265,7 @@ find_or_allocate_block(struct nfs4_lockowner *lo, struct knfsd_fh *fh,
> > >>>  static void
> > >>>  free_blocked_lock(struct nfsd4_blocked_lock *nbl)
> > >>>  {
> > >>> + locks_delete_block(&nbl->nbl_lock);
> > >>>   locks_release_private(&nbl->nbl_lock);
> > >>
> > >> Thanks for tracking this down.
> > >>
> > >> An implication of this bug and fix is that we need to be particularly
> > >> careful to make sure locks_delete_block() is called on all relevant
> > >> paths.
> > >> Can we make that easier?  My first thought was to include the call in
> > >> locks_release_private, but lockd calls the two quite separately and it
> > >> certainly seems appropriate that locks_delete_block should be called
> > >> asap, but locks_release_private() can be delayed.
> > >>
> > >> Also cifs calls locks_delete_block, but never calls
> > >> locks_release_private, so it wouldn't help there.
> > >>
> > >> Looking at cifs, I think there is a call missing there too.
> > >> cifs_posix_lock_set() *doesn't* always call locks_delete_block() after
> > >> waiting.  In particular, if ->can_cache_brlcks becomes true while
> > >> waiting then I don't think the behaviour is right.... though I'm not
> > >> sure it is right for other reasons.  It looks like the return value
> > >> should be 1 in that case, but it'll be zero.
> > >>
> > >> But back to my question about making it easier, move the BUG_ON()
> > >> calls from locks_free_lock() into locks_release_private().
> > >>
> > >> ??
> > >>
> > >> Thanks,
> > >> NeilBrown
> > >>
> > >>
> > >>>   kfree(nbl);
> > >>>  }
> > >>> @@ -293,7 +294,6 @@ remove_blocked_locks(struct nfs4_lockowner *lo)
> > >>>           nbl = list_first_entry(&reaplist, struct nfsd4_blocked_lock,
> > >>>                                   nbl_lru);
> > >>>           list_del_init(&nbl->nbl_lru);
> > >>> -         locks_delete_block(&nbl->nbl_lock);
> > >>>           free_blocked_lock(nbl);
> > >>>   }
> > >>>  }
> > >>> @@ -4863,7 +4863,6 @@ nfs4_laundromat(struct nfsd_net *nn)
> > >>>           nbl = list_first_entry(&reaplist,
> > >>>                                   struct nfsd4_blocked_lock, nbl_lru);
> > >>>           list_del_init(&nbl->nbl_lru);
> > >>> -         locks_delete_block(&nbl->nbl_lock);
> > >>>           free_blocked_lock(nbl);
> > >>>   }
> > >>>  out:
> > >>> --
> > >>> 2.20.1
> > >
> > >

Patch
diff mbox series

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 6a45fb00c5fc..e87e15df2044 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -265,6 +265,7 @@  find_or_allocate_block(struct nfs4_lockowner *lo, struct knfsd_fh *fh,
 static void
 free_blocked_lock(struct nfsd4_blocked_lock *nbl)
 {
+	locks_delete_block(&nbl->nbl_lock);
 	locks_release_private(&nbl->nbl_lock);
 	kfree(nbl);
 }
@@ -293,7 +294,6 @@  remove_blocked_locks(struct nfs4_lockowner *lo)
 		nbl = list_first_entry(&reaplist, struct nfsd4_blocked_lock,
 					nbl_lru);
 		list_del_init(&nbl->nbl_lru);
-		locks_delete_block(&nbl->nbl_lock);
 		free_blocked_lock(nbl);
 	}
 }
@@ -4863,7 +4863,6 @@  nfs4_laundromat(struct nfsd_net *nn)
 		nbl = list_first_entry(&reaplist,
 					struct nfsd4_blocked_lock, nbl_lru);
 		list_del_init(&nbl->nbl_lru);
-		locks_delete_block(&nbl->nbl_lock);
 		free_blocked_lock(nbl);
 	}
 out: