lkml.org 
[lkml]   [2021]   [Dec]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 3/3] nfs v2/3: nlmclnt_lock: handle async processing of F_SETLK with FL_SLEEP
    Date
    nfsd and lockd use F_SETLK cmd with the FL_SLEEP flag set to request
    asynchronous processing of blocking locks.

    Currently nfs v2/3 handles such requests by using nlmclnt_lock() ->
    do_vfs_lock() -> locks_lock_inode_wait() function which is blocked
    if request have FL_SLEEP flag set.

    To handle them correctly FL_SLEEP flag should be temporarily reset
    before executing the locks_lock_inode_wait() function.

    Additionally block flag is forced to set, to translate blocking lock to
    remote nfs server, expecting it supports async processing of the blocking
    locks too.

    https://bugzilla.kernel.org/show_bug.cgi?id=215383
    Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
    ---
    fs/lockd/clntproc.c | 14 ++++++++++++--
    1 file changed, 12 insertions(+), 2 deletions(-)

    diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
    index 99fffc9cb958..5941aa7c9cc9 100644
    --- a/fs/lockd/clntproc.c
    +++ b/fs/lockd/clntproc.c
    @@ -519,11 +519,18 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
    unsigned char fl_flags = fl->fl_flags;
    unsigned char fl_type;
    int status = -ENOLCK;
    + bool async = false;

    if (nsm_monitor(host) < 0)
    goto out;
    req->a_args.state = nsm_local_state;

    + async = !req->a_args.block &&
    + ((fl_flags & FL_SLEEP_POSIX) == FL_SLEEP_POSIX);
    + if (async) {
    + fl->fl_flags &= ~FL_SLEEP;
    + req->a_args.block = 1;
    + }
    fl->fl_flags |= FL_ACCESS;
    status = do_vfs_lock(fl);
    fl->fl_flags = fl_flags;
    @@ -573,8 +580,11 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
    up_read(&host->h_rwsem);
    goto again;
    }
    - /* Ensure the resulting lock will get added to granted list */
    - fl->fl_flags |= FL_SLEEP;
    + if (async)
    + fl->fl_flags &= ~FL_SLEEP;
    + else
    + /* Ensure the resulting lock will get added to granted list */
    + fl->fl_flags |= FL_SLEEP;
    if (do_vfs_lock(fl) < 0)
    printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __func__);
    up_read(&host->h_rwsem);
    --
    2.25.1
    \
     
     \ /
      Last update: 2021-12-29 09:25    [W:5.086 / U:0.256 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site