On Thu, 2020-01-09 at 10:05 +0800, Xiubo Li wrote: > On 2020/1/6 23:35, Jeff Layton wrote: > > Currently, we just assume that it will stick around by virtue of the > > submitter's reference, but later patches will allow the syscall to > > return early and we can't rely on that reference at that point. > > > > Take an extra reference to the inode when setting r_parent and release > > it when releasing the request. > > > > Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx> > > --- > > fs/ceph/mds_client.c | 8 ++++++-- > > 1 file changed, 6 insertions(+), 2 deletions(-) > > > > diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c > > index 94cce2ab92c4..b7122f682678 100644 > > --- a/fs/ceph/mds_client.c > > +++ b/fs/ceph/mds_client.c > > @@ -708,8 +708,10 @@ void ceph_mdsc_release_request(struct kref *kref) > > /* avoid calling iput_final() in mds dispatch threads */ > > ceph_async_iput(req->r_inode); > > } > > - if (req->r_parent) > > + if (req->r_parent) { > > ceph_put_cap_refs(ceph_inode(req->r_parent), CEPH_CAP_PIN); > > + ceph_async_iput(req->r_parent); > > + } > > ceph_async_iput(req->r_target_inode); > > if (req->r_dentry) > > dput(req->r_dentry); > > @@ -2706,8 +2708,10 @@ int ceph_mdsc_submit_request(struct ceph_mds_client *mdsc, struct inode *dir, > > /* take CAP_PIN refs for r_inode, r_parent, r_old_dentry */ > > if (req->r_inode) > > ceph_get_cap_refs(ceph_inode(req->r_inode), CEPH_CAP_PIN); > > - if (req->r_parent) > > + if (req->r_parent) { > > ceph_get_cap_refs(ceph_inode(req->r_parent), CEPH_CAP_PIN); > > + ihold(req->r_parent); > > + } > > This might also fix another issue when the mdsc request is timedout and > returns to the vfs, then the r_parent maybe released in vfs. And then if > we reference it again in mdsc handle_reply() --> > ceph_mdsc_release_request(), some unknown issues may happen later ?? > AIUI, when a timeout occurs, the req is unhashed such that handle_reply can't find it. So, I doubt this affects that one way or another. > > if (req->r_old_dentry_dir) > > ceph_get_cap_refs(ceph_inode(req->r_old_dentry_dir), > > CEPH_CAP_PIN); > > -- Jeff Layton <jlayton@xxxxxxxxxx>