Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8996f4f2 authored by Yan, Zheng's avatar Yan, Zheng
Browse files

ceph: fix ceph_fh_to_parent()



ceph_fh_to_parent() returns dentry that corresponds to the 'ino' field
of struct ceph_nfs_confh. This is wrong, it should return dentry that
corresponds to the 'parent_ino' field.

Signed-off-by: default avatarYan, Zheng <zheng.z.yan@intel.com>
Reviewed-by: default avatarSage Weil <sage@inktank.com>
parent 9017c2ec
Loading
Loading
Loading
Loading
+9 −33
Original line number Diff line number Diff line
@@ -181,48 +181,24 @@ struct dentry *ceph_get_parent(struct dentry *child)
}

/*
 * get parent, if possible.
 *
 * FIXME: we could do better by querying the mds to discover the
 * parent.
 * convert regular fh to parent
 */
static struct dentry *ceph_fh_to_parent(struct super_block *sb,
					struct fid *fid,
					int fh_len, int fh_type)
{
	struct ceph_nfs_confh *cfh = (void *)fid->raw;
	struct ceph_vino vino;
	struct inode *inode;
	struct dentry *dentry;
	int err;

	if (fh_type == 1)
		return ERR_PTR(-ESTALE);
	if (fh_type != FILEID_INO32_GEN_PARENT)
		return NULL;
	if (fh_len < sizeof(*cfh) / 4)
		return ERR_PTR(-ESTALE);

	pr_debug("fh_to_parent %llx/%d\n", cfh->parent_ino,
		 cfh->parent_name_hash);

	vino.ino = cfh->ino;
	vino.snap = CEPH_NOSNAP;
	inode = ceph_find_inode(sb, vino);
	if (!inode)
		return ERR_PTR(-ESTALE);
		return NULL;

	dentry = d_obtain_alias(inode);
	if (IS_ERR(dentry)) {
		pr_err("fh_to_parent %llx -- inode %p but ENOMEM\n",
		       cfh->ino, inode);
		iput(inode);
		return dentry;
	}
	err = ceph_init_dentry(dentry);
	if (err < 0) {
		iput(inode);
		return ERR_PTR(err);
	}
	dout("fh_to_parent %llx %p dentry %p\n", cfh->ino, inode, dentry);
	dout("fh_to_parent %llx\n", cfh->parent_ino);
	dentry = __get_parent(sb, NULL, cfh->ino);
	if (IS_ERR(dentry) && PTR_ERR(dentry) == -ENOENT)
		dentry = __fh_to_dentry(sb, cfh->parent_ino);
	return dentry;
}