Message ID | 20190523081345.20410-5-zyan@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/8] ceph: fix error handling in ceph_get_caps() | expand |
On Thu, 2019-05-23 at 16:13 +0800, Yan, Zheng wrote: > 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> > --- > 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; > } > Reviewed-by: Jeff Layton <jlayton@redhat.com>
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; }
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> --- fs/ceph/dir.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-)