Re: [PATCH RFC 1/1] nfsd: Initial implementation of NFSv4 Courteous Server

dai.ngo
2021-06-30T18:49:30Z

On 6/30/21 11:05 AM, J. Bruce Fields wrote:
> On Wed, Jun 30, 2021 at 10:51:27AM -0700, dai.ngo@oracle.com wrote:
>>> On 6/28/21 1:23 PM, J. Bruce Fields wrote:
>>>> where ->fl_expire_lock is a new lock callback with second
>>>> argument "check"
>>>> where:
>>>>
>>>>     check = 1 means: just check whether this lock could be freed
>> Why do we need this, is there a use case for it? can we just always try
>> to expire the lock and return success/fail?
> We can't expire the client while holding the flc_lock. And once we drop
> that lock we need to restart the loop. Clearly we can't do that every
> time.
>
> (So, my code was wrong, it should have been:
>
>
> if (fl->fl_lops->fl_expire_lock(fl, 1)) {
> spin_unlock(&ct->flc_lock);
> fl->fl_lops->fl_expire_locks(fl, 0);
> goto retry;
> }
>
> )

This is what I currently have:

retry:
list_for_each_entry(fl, &ctx->flc_posix, fl_list) {
if (!posix_locks_conflict(request, fl))
continue;

if (fl->fl_lmops && fl->fl_lmops->lm_expire_lock) {
spin_unlock(&ctx->flc_lock);
ret = fl->fl_lmops->lm_expire_lock(fl, 0);
spin_lock(&ctx->flc_lock);
if (ret)
goto retry;
}

if (conflock)
locks_copy_conflock(conflock, fl);

>
> But the 1 and 0 cases are starting to look pretty different; maybe they
> should be two different callbacks.

why the case of 1 (test only) is needed, who would use this call?

-Dai

>
> --b.