lkml.org 
[lkml]   [2019]   [Jul]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.2 34/85] ceph: fix dir_lease_is_valid()
    Date
    From: "Yan, Zheng" <zyan@redhat.com>

    [ Upstream commit feab6ac25dbfe3ab96299cb741925dc8d2da0caf ]

    It should call __ceph_dentry_dir_lease_touch() under dentry->d_lock.
    Besides, ceph_dentry(dentry) can be NULL when called by LOOKUP_RCU
    d_revalidate()

    Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
    Reviewed-by: Jeff Layton <jlayton@redhat.com>
    Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/ceph/dir.c | 26 +++++++++++++++++---------
    1 file changed, 17 insertions(+), 9 deletions(-)

    diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
    index 0637149fb9f9..1271024a3797 100644
    --- a/fs/ceph/dir.c
    +++ b/fs/ceph/dir.c
    @@ -1512,18 +1512,26 @@ static int __dir_lease_try_check(const struct dentry *dentry)
    static int dir_lease_is_valid(struct inode *dir, struct dentry *dentry)
    {
    struct ceph_inode_info *ci = ceph_inode(dir);
    - struct ceph_dentry_info *di = ceph_dentry(dentry);
    - int valid = 0;
    + int valid;
    + int shared_gen;

    spin_lock(&ci->i_ceph_lock);
    - if (atomic_read(&ci->i_shared_gen) == di->lease_shared_gen)
    - valid = __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1);
    + valid = __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1);
    + shared_gen = atomic_read(&ci->i_shared_gen);
    spin_unlock(&ci->i_ceph_lock);
    - if (valid)
    - __ceph_dentry_dir_lease_touch(di);
    - dout("dir_lease_is_valid dir %p v%u dentry %p v%u = %d\n",
    - dir, (unsigned)atomic_read(&ci->i_shared_gen),
    - dentry, (unsigned)di->lease_shared_gen, valid);
    + if (valid) {
    + struct ceph_dentry_info *di;
    + spin_lock(&dentry->d_lock);
    + di = ceph_dentry(dentry);
    + if (dir == d_inode(dentry->d_parent) &&
    + di && di->lease_shared_gen == shared_gen)
    + __ceph_dentry_dir_lease_touch(di);
    + else
    + valid = 0;
    + spin_unlock(&dentry->d_lock);
    + }
    + dout("dir_lease_is_valid dir %p v%u dentry %p = %d\n",
    + dir, (unsigned)atomic_read(&ci->i_shared_gen), dentry, valid);
    return valid;
    }

    --
    2.20.1
    \
     
     \ /
      Last update: 2019-07-26 16:00    [W:4.075 / U:0.060 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site