lkml.org 
[lkml]   [2020]   [Jan]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 325/639] afs: Fix AFS file locking to allow fine grained locks
    Date
    From: David Howells <dhowells@redhat.com>

    [ Upstream commit 68ce801ffd82e72d5005ab5458e8b9e59f24d9cc ]

    Fix AFS file locking to allow fine grained locks as some applications, such
    as firefox, won't work if they can't take such locks on certain state files
    - thereby preventing the use of kAFS to distribute a home directory.

    Note that this cannot be made completely functional as the protocol only
    has provision for whole-file locks, so there exists the possibility of a
    process deadlocking itself by getting a partial read-lock on a file first
    and then trying to get a non-overlapping write-lock - but we got the
    server's read lock with the first lock, so we're now stuck.

    OpenAFS solves this by just granting any partial-range lock directly
    without consulting the server - and hoping there's no remote collision. I
    want to implement that in a separate patch and it requires a bit more
    thought.

    Fixes: 8d6c554126b8 ("AFS: implement file locking")
    Reported-by: Jonathan Billings <jsbillings@jsbillings.org>
    Signed-off-by: David Howells <dhowells@redhat.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/afs/flock.c | 23 +++++++++--------------
    1 file changed, 9 insertions(+), 14 deletions(-)

    diff --git a/fs/afs/flock.c b/fs/afs/flock.c
    index 1bb300ef362b0..dffbb456629c9 100644
    --- a/fs/afs/flock.c
    +++ b/fs/afs/flock.c
    @@ -432,10 +432,6 @@ static int afs_do_setlk(struct file *file, struct file_lock *fl)

    _enter("{%x:%u},%u", vnode->fid.vid, vnode->fid.vnode, fl->fl_type);

    - /* only whole-file locks are supported */
    - if (fl->fl_start != 0 || fl->fl_end != OFFSET_MAX)
    - return -EINVAL;
    -
    fl->fl_ops = &afs_lock_ops;
    INIT_LIST_HEAD(&fl->fl_u.afs.link);
    fl->fl_u.afs.state = AFS_LOCK_PENDING;
    @@ -587,10 +583,6 @@ static int afs_do_unlk(struct file *file, struct file_lock *fl)
    /* Flush all pending writes before doing anything with locks. */
    vfs_fsync(file, 0);

    - /* only whole-file unlocks are supported */
    - if (fl->fl_start != 0 || fl->fl_end != OFFSET_MAX)
    - return -EINVAL;
    -
    ret = posix_lock_file(file, fl, NULL);
    _leave(" = %d [%u]", ret, vnode->lock_state);
    return ret;
    @@ -618,12 +610,15 @@ static int afs_do_getlk(struct file *file, struct file_lock *fl)
    goto error;

    lock_count = READ_ONCE(vnode->status.lock_count);
    - if (lock_count > 0)
    - fl->fl_type = F_RDLCK;
    - else
    - fl->fl_type = F_WRLCK;
    - fl->fl_start = 0;
    - fl->fl_end = OFFSET_MAX;
    + if (lock_count != 0) {
    + if (lock_count > 0)
    + fl->fl_type = F_RDLCK;
    + else
    + fl->fl_type = F_WRLCK;
    + fl->fl_start = 0;
    + fl->fl_end = OFFSET_MAX;
    + fl->fl_pid = 0;
    + }
    }

    ret = 0;
    --
    2.20.1


    \
     
     \ /
      Last update: 2020-01-24 12:19    [W:6.133 / U:0.392 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site