The callback uses LOOKUPPARENT MDS request to find parent. Signed-off-by: Yan, Zheng <zheng.z.yan@xxxxxxxxx> --- fs/ceph/export.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/fs/ceph/export.c b/fs/ceph/export.c index 017af26..817d370 100644 --- a/fs/ceph/export.c +++ b/fs/ceph/export.c @@ -139,8 +139,52 @@ static struct dentry *ceph_fh_to_parent(struct super_block *sb, return __fh_to_dentry(sb, cfh->parent_ino); } +static struct dentry *ceph_get_parent(struct dentry *child) +{ + struct ceph_mds_client *mdsc; + struct ceph_mds_request *req; + struct inode *inode; + struct dentry *dentry; + int err; + + /* don't re-export snaps */ + if (ceph_snap(child->d_inode) != CEPH_NOSNAP) + return ERR_PTR(-EINVAL); + + mdsc = ceph_inode_to_client(child->d_inode)->mdsc; + req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPPARENT, + USE_ANY_MDS); + if (IS_ERR(req)) + return ERR_CAST(req); + + req->r_ino1 = ceph_vino(child->d_inode); + req->r_num_caps = 1; + err = ceph_mdsc_do_request(mdsc, NULL, req); + inode = req->r_target_inode; + if (inode) + ihold(inode); + ceph_mdsc_put_request(req); + if (!inode) + return ERR_PTR(-ESTALE); + + dentry = d_obtain_alias(inode); + if (IS_ERR(dentry)) { + iput(inode); + return dentry; + } + err = ceph_init_dentry(dentry); + if (err < 0) { + dput(dentry); + return ERR_PTR(err); + } + dout("get_parent child %p parent %llx %p\n", + child, ceph_ino(inode), dentry); + return dentry; +} + const struct export_operations ceph_export_ops = { .encode_fh = ceph_encode_fh, .fh_to_dentry = ceph_fh_to_dentry, .fh_to_parent = ceph_fh_to_parent, + .get_parent = ceph_get_parent, }; -- 1.8.5.3 -- To unsubscribe from this list: send the line "unsubscribe ceph-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html